]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmf.c 
54c5fc87788192c3ad7936e1de36bc818ce17435
   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  //-----------------------------------------------------------------------------   13  #include  "./nonce2key/nonce2key.h"   15  static int  CmdHelp ( const char  * Cmd
);   17  int  CmdHF14AMifare ( const char  * Cmd
)   20          uint32_t  nt 
=  0 ,  nr 
=  0 ;   21          uint64_t  par_list 
=  0 ,  ks_list 
=  0 ,  r_key 
=  0 ;   24          UsbCommand c 
= { CMD_READER_MIFARE
, { true ,  0 ,  0 }};   27          printf ( "------------------------------------------------------------------------- \n " );   28          printf ( "Executing command. Expected execution time: 25sec on average  :-) \n " );   29          printf ( "Press button on the proxmark3 device to abort both proxmark3 and client. \n " );   30          printf ( "------------------------------------------------------------------------- \n " );   38          while  ( ukbhit ())         getchar ();   46                          printf ( " \n aborted via keyboard! \n " );   51                  if  ( WaitForResponseTimeout ( CMD_ACK
, & resp
,  1000 )) {   53                          uid 
= ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+   0 ,  4 );   54                          nt 
=  ( uint32_t ) bytes_to_num ( resp
. d
. asBytes 
+   4 ,  4 );   55                          par_list 
=  bytes_to_num ( resp
. d
. asBytes 
+   8 ,  8 );   56                          ks_list 
=  bytes_to_num ( resp
. d
. asBytes 
+   16 ,  8 );   57                          nr 
=  bytes_to_num ( resp
. d
. asBytes 
+  24 ,  4 );   60                                  case  - 1  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;   61                                  case  - 2  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests). \n " );  break ;   62                                  case  - 3  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator is not predictable). \n " );  break ;   63                                  case  - 4  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown" );   64                                                          PrintAndLog ( "generating polynomial with 16 effective bits only, but shows unexpected behaviour. \n " );  break ;   74          if  ( isOK 
!=  1 )  return  1 ;   76          // execute original function from util nonce2key   77          if  ( nonce2key ( uid
,  nt
,  nr
,  par_list
,  ks_list
, & r_key
)) {   79                  PrintAndLog ( "Key not found (lfsr_common_prefix list is null). Nt= %0 8x" ,  nt
);       80                  PrintAndLog ( "Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce..." );   85                  printf ( "------------------------------------------------------------------ \n " );   86                  PrintAndLog ( "Found valid key: %0 12"  PRIx64 
"  \n " ,  r_key
);   93  int  CmdHF14AMfWrBl ( const char  * Cmd
)   97          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };   98          uint8_t  bldata
[ 16 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 };  103                  PrintAndLog ( "Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>" );  104                  PrintAndLog ( "        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F" );  108          blockNo 
=  param_get8 ( Cmd
,  0 );  109          cmdp 
=  param_getchar ( Cmd
,  1 );  111                  PrintAndLog ( "Key type must be A or B" );  114          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  115          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  116                  PrintAndLog ( "Key must include 12 HEX symbols" );  119          if  ( param_gethex ( Cmd
,  3 ,  bldata
,  32 )) {  120                  PrintAndLog ( "Block data must include 32 HEX symbols" );  123          PrintAndLog ( "--block no: %d , key type: %c , key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  124          PrintAndLog ( "--data:  %s " ,  sprint_hex ( bldata
,  16 ));  126    UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { blockNo
,  keyType
,  0 }};  127          memcpy ( c
. d
. asBytes
,  key
,  6 );  128          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );  132          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  133                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  134                  PrintAndLog ( "isOk: %0 2x" ,  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: %d , key type: %c , key: %s  " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  170    UsbCommand c 
= { CMD_MIFARE_READBL
, { blockNo
,  keyType
,  0 }};  171          memcpy ( c
. d
. asBytes
,  key
,  6 );  175          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  176                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  177                  uint8_t  * data 
=  resp
. d
. asBytes
;  180                          PrintAndLog ( "isOk: %0 2x data: %s " ,  isOK
,  sprint_hex ( data
,  16 ));  182                          PrintAndLog ( "isOk: %0 2x" ,  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 };  197          uint8_t  * data  
=  NULL
;  201                  PrintAndLog ( "Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>" );  202                  PrintAndLog ( "        sample: hf mf rdsc 0 A FFFFFFFFFFFF " );  206          sectorNo 
=  param_get8 ( Cmd
,  0 );  208                  PrintAndLog ( "Sector number must be less than 40" );  211          cmdp 
=  param_getchar ( Cmd
,  1 );  212          if  ( cmdp 
!=  'a'  &&  cmdp 
!=  'A'  &&  cmdp 
!=  'b'  &&  cmdp 
!=  'B' ) {  213                  PrintAndLog ( "Key type must be A or B" );  216          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  217          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  218                  PrintAndLog ( "Key must include 12 HEX symbols" );  221          PrintAndLog ( "--sector no: %d  key type: %c  key: %s  " ,  sectorNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  223          UsbCommand c 
= { CMD_MIFARE_READSC
, { sectorNo
,  keyType
,  0 }};  224          memcpy ( c
. d
. asBytes
,  key
,  6 );  229          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  230                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  231                  data  
=  resp
. d
. asBytes
;  233                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  235                          for  ( i 
=  0 ;  i 
< ( sectorNo
< 32 ? 3 : 15 );  i
++) {  236                                  PrintAndLog ( "data   :  %s " ,  sprint_hex ( data 
+  i 
*  16 ,  16 ));  238                          PrintAndLog ( "trailer:  %s " ,  sprint_hex ( data 
+ ( sectorNo
< 32 ? 3 : 15 ) *  16 ,  16 ));  241                  PrintAndLog ( "Command execute timeout" );  247  uint8_t  FirstBlockOfSector ( uint8_t  sectorNo
)  252                  return  32  *  4  + ( sectorNo 
-  32 ) *  16 ;  256  uint8_t  NumBlocksPerSector ( uint8_t  sectorNo
)  265  int  CmdHF14AMfDump ( const char  * Cmd
)  267          uint8_t  sectorNo
,  blockNo
;  271          uint8_t  rights
[ 40 ][ 4 ];  272          uint8_t  carddata
[ 256 ][ 16 ];  273          uint8_t  numSectors 
=  16 ;  280          char  cmdp 
=  param_getchar ( Cmd
,  0 );  282                  case  '0'  :  numSectors 
=  5 ;  break ;  284                  case  '\0' :  numSectors 
=  16 ;  break ;  285                  case  '2'  :  numSectors 
=  32 ;  break ;  286                  case  '4'  :  numSectors 
=  40 ;  break ;  287                  default :    numSectors 
=  16 ;  290          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  291                  PrintAndLog ( "Usage:   hf mf dump [card memory]" );  292                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  294                  PrintAndLog ( "Samples: hf mf dump" );  295                  PrintAndLog ( "         hf mf dump 4" );  299          if  (( fin 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  300                  PrintAndLog ( "Could not find file dumpkeys.bin" );  304          // Read keys A from file  305          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  306                  if  ( fread (  keyA
[ sectorNo
],  1 ,  6 ,  fin 
) ==  0 ) {  307                          PrintAndLog ( "File reading error." );  313          // Read keys B from file  314          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  315                  if  ( fread (  keyB
[ sectorNo
],  1 ,  6 ,  fin 
) ==  0 ) {  316                          PrintAndLog ( "File reading error." );  324          PrintAndLog ( "|-----------------------------------------|" );  325          PrintAndLog ( "|------ Reading sector access bits...-----|" );  326          PrintAndLog ( "|-----------------------------------------|" );  328          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  329                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  0 ,  0 }};  330                  memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  333                  if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  334                          uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  335                          uint8_t  * data  
=  resp
. d
. asBytes
;  337                                  rights
[ sectorNo
][ 0 ] = (( data
[ 7 ] &  0x10 )>> 2 ) | (( data
[ 8 ] &  0x1 )<< 1 ) | (( data
[ 8 ] &  0x10 )>> 4 );  // C1C2C3 for data area 0  338                                  rights
[ sectorNo
][ 1 ] = (( data
[ 7 ] &  0x20 )>> 3 ) | (( data
[ 8 ] &  0x2 )<< 0 ) | (( data
[ 8 ] &  0x20 )>> 5 );  // C1C2C3 for data area 1  339                                  rights
[ sectorNo
][ 2 ] = (( data
[ 7 ] &  0x40 )>> 4 ) | (( data
[ 8 ] &  0x4 )>> 1 ) | (( data
[ 8 ] &  0x40 )>> 6 );  // C1C2C3 for data area 2  340                                  rights
[ sectorNo
][ 3 ] = (( data
[ 7 ] &  0x80 )>> 5 ) | (( data
[ 8 ] &  0x8 )>> 2 ) | (( data
[ 8 ] &  0x80 )>> 7 );  // C1C2C3 for sector trailer  342                                  PrintAndLog ( "Could not get access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  343                                  rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  344                                  rights
[ sectorNo
][ 3 ] =  0x01 ;  347                          PrintAndLog ( "Command execute timeout when trying to read access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  348                          rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  349                          rights
[ sectorNo
][ 3 ] =  0x01 ;  353          PrintAndLog ( "|-----------------------------------------|" );  354          PrintAndLog ( "|----- Dumping all blocks to file... -----|" );  355          PrintAndLog ( "|-----------------------------------------|" );  358          for  ( sectorNo 
=  0 ;  isOK 
&&  sectorNo 
<  numSectors
;  sectorNo
++) {  359                  for  ( blockNo 
=  0 ;  isOK 
&&  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  360                          bool  received 
=  false ;  362                          if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. At least the Access Conditions can always be read with key A.   363                                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  364                                  memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  366                                  received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  367                          }  else  {                                                                                                 // data block. Check if it can be read with key A or key B  368                                  uint8_t  data_area 
=  sectorNo
< 32 ? blockNo
: blockNo
/ 5 ;  369                                  if  (( rights
[ sectorNo
][ data_area
] ==  0x03 ) || ( rights
[ sectorNo
][ data_area
] ==  0x05 )) {    // only key B would work  370                                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  1 ,  0 }};  371                                          memcpy ( c
. d
. asBytes
,  keyB
[ sectorNo
],  6 );  373                                          received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  374                                  }  else if  ( rights
[ sectorNo
][ data_area
] ==  0x07 ) {                                                                                // no key would work  376                                          PrintAndLog ( "Access rights do not allow reading of sector  %2 d block  %3 d" ,  sectorNo
,  blockNo
);  377                                  }  else  {                                                                                                                                                                 // key A would work  378                                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  379                                          memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  381                                          received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  386                                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  387                                  uint8_t  * data  
=  resp
. d
. asBytes
;  388                                  if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. Fill in the keys.  389                                          data
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  390                                          data
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  391                                          data
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  392                                          data
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  393                                          data
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  394                                          data
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  395                                          data
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  396                                          data
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  397                                          data
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  398                                          data
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  399                                          data
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  400                                          data
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  403                                          memcpy ( carddata
[ FirstBlockOfSector ( sectorNo
) +  blockNo
],  data
,  16 );  404                      PrintAndLog ( "Successfully read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  406                                          PrintAndLog ( "Could not read block  %2 d of sector  %2 d" ,  blockNo
,  sectorNo
);  412                                  PrintAndLog ( "Command execute timeout when trying to read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  419                  if  (( fout 
=  fopen ( "dumpdata.bin" , "wb" )) ==  NULL
) {   420                          PrintAndLog ( "Could not create file name dumpdata.bin" );  423                  uint16_t  numblocks 
=  FirstBlockOfSector ( numSectors 
-  1 ) +  NumBlocksPerSector ( numSectors 
-  1 );  424                  fwrite ( carddata
,  1 ,  16 * numblocks
,  fout
);  426                  PrintAndLog ( "Dumped  %d  blocks ( %d  bytes) to file dumpdata.bin" ,  numblocks
,  16 * numblocks
);  432  int  CmdHF14AMfRestore ( const char  * Cmd
)  434          uint8_t  sectorNo
, blockNo
;  436          uint8_t  key
[ 6 ] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };  437          uint8_t  bldata
[ 16 ] = { 0x00 };  445          char  cmdp 
=  param_getchar ( Cmd
,  0 );  447                  case  '0'  :  numSectors 
=  5 ;  break ;  449                  case  '\0' :  numSectors 
=  16 ;  break ;  450                  case  '2'  :  numSectors 
=  32 ;  break ;  451                  case  '4'  :  numSectors 
=  40 ;  break ;  452                  default :    numSectors 
=  16 ;  455          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  456                  PrintAndLog ( "Usage:   hf mf restore [card memory]" );  457                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  459                  PrintAndLog ( "Samples: hf mf restore" );  460                  PrintAndLog ( "         hf mf restore 4" );  464          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  465                  PrintAndLog ( "Could not find file dumpkeys.bin" );  469          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  470                  if  ( fread ( keyA
[ sectorNo
],  1 ,  6 ,  fkeys
) ==  0 ) {  471                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  478          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  479                  if  ( fread ( keyB
[ sectorNo
],  1 ,  6 ,  fkeys
) ==  0 ) {  480                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  488          if  (( fdump 
=  fopen ( "dumpdata.bin" , "rb" )) ==  NULL
) {  489                  PrintAndLog ( "Could not find file dumpdata.bin" );  492          PrintAndLog ( "Restoring dumpdata.bin to card" );  494          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  495                  for ( blockNo 
=  0 ;  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  496                          UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  keyType
,  0 }};  497                          memcpy ( c
. d
. asBytes
,  key
,  6 );  499                          if  ( fread ( bldata
,  1 ,  16 ,  fdump
) ==  0 ) {  500                                  PrintAndLog ( "File reading error (dumpdata.bin)." );  505                          if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {       // sector trailer  506                                  bldata
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  507                                  bldata
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  508                                  bldata
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  509                                  bldata
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  510                                  bldata
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  511                                  bldata
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  512                                  bldata
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  513                                  bldata
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  514                                  bldata
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  515                                  bldata
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  516                                  bldata
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  517                                  bldata
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  520                          PrintAndLog ( "Writing to block  %3 d:  %s " ,  FirstBlockOfSector ( sectorNo
) +  blockNo
,  sprint_hex ( bldata
,  16 ));  522                          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );  526                          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  527                                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  528                                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  530                                  PrintAndLog ( "Command execute timeout" );  539  int  CmdHF14AMfNested ( const char  * Cmd
)  541          int  i
,  j
,  res
,  iterations
;  542          sector 
* e_sector 
=  NULL
;  545          uint8_t  trgBlockNo 
=  0 ;  546          uint8_t  trgKeyType 
=  0 ;  547          uint8_t  SectorsCnt 
=  0 ;  548          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  549          uint8_t  keyBlock
[ 14 * 6 ];  551          bool  transferToEml 
=  false ;  553          bool  createDumpFile 
=  false ;  555          uint8_t  standart
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  556          uint8_t  tempkey
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  561                  PrintAndLog ( "Usage:" );  562                  PrintAndLog ( " all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)> [t,d]" );  563                  PrintAndLog ( " one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)>" );  564                  PrintAndLog ( "               <target block number> <target key A/B> [t]" );  565                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" );  566                  PrintAndLog ( "t - transfer keys into emulator memory" );  567                  PrintAndLog ( "d - write keys to binary file" );  569                  PrintAndLog ( "      sample1: hf mf nested 1 0 A FFFFFFFFFFFF " );  570                  PrintAndLog ( "      sample2: hf mf nested 1 0 A FFFFFFFFFFFF t " );  571                  PrintAndLog ( "      sample3: hf mf nested 1 0 A FFFFFFFFFFFF d " );  572                  PrintAndLog ( "      sample4: hf mf nested o 0 A FFFFFFFFFFFF 4 A" );  576          cmdp 
=  param_getchar ( Cmd
,  0 );  577          blockNo 
=  param_get8 ( Cmd
,  1 );  578          ctmp 
=  param_getchar ( Cmd
,  2 );  580          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  581                  PrintAndLog ( "Key type must be A or B" );  585          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )   588          if  ( param_gethex ( Cmd
,  3 ,  key
,  12 )) {  589                  PrintAndLog ( "Key must include 12 HEX symbols" );  593          if  ( cmdp 
==  'o'  ||  cmdp 
==  'O' ) {  595                  trgBlockNo 
=  param_get8 ( Cmd
,  4 );  596                  ctmp 
=  param_getchar ( Cmd
,  5 );  597                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  598                          PrintAndLog ( "Target key type must be A or B" );  601                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )   606                          case  '0' :  SectorsCnt 
=  05 ;  break ;  607                          case  '1' :  SectorsCnt 
=  16 ;  break ;  608                          case  '2' :  SectorsCnt 
=  32 ;  break ;  609                          case  '4' :  SectorsCnt 
=  40 ;  break ;  610                          default :   SectorsCnt 
=  16 ;  614          ctmp 
=  param_getchar ( Cmd
,  4 );  615          if               ( ctmp 
==  't'  ||  ctmp 
==  'T' )  transferToEml 
=  true ;  616          else if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  createDumpFile 
=  true ;  618          ctmp 
=  param_getchar ( Cmd
,  6 );  619          transferToEml 
|= ( ctmp 
==  't'  ||  ctmp 
==  'T' );  620          transferToEml 
|= ( ctmp 
==  'd'  ||  ctmp 
==  'D' );  623                  PrintAndLog ( "--target block no: %3 d, target key type: %c  " ,  trgBlockNo
,  trgKeyType
? 'B' : 'A' );  624                  int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  trgBlockNo
,  trgKeyType
,  keyBlock
,  true );  627                                  case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  628                                  case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  629                                  case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  630                                  default  :  PrintAndLog ( "Unknown Error. \n " );  634                  key64 
=  bytes_to_num ( keyBlock
,  6 );  636                          PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  638                          // transfer key to the emulator  640                                  uint8_t  sectortrailer
;  641                                  if  ( trgBlockNo 
<  32 * 4 ) {         // 4 block sector  642                                          sectortrailer 
= ( trgBlockNo 
&  0x03 ) +  3 ;  643                                  }  else  {                                         // 16 block sector  644                                          sectortrailer 
= ( trgBlockNo 
&  0x0f ) +  15 ;  646                                  mfEmlGetMem ( keyBlock
,  sectortrailer
,  1 );  649                                          num_to_bytes ( key64
,  6 ,  keyBlock
);  651                                          num_to_bytes ( key64
,  6 , & keyBlock
[ 10 ]);  652                                  mfEmlSetMem ( keyBlock
,  sectortrailer
,  1 );                  655                          PrintAndLog ( "No valid key found" );  658          else  {  // ------------------------------------  multiple sectors working  662                  e_sector 
=  calloc ( SectorsCnt
,  sizeof ( sector
));  663                  if  ( e_sector 
==  NULL
)  return  1 ;  665                  //test current key and additional standard keys first  666                  memcpy ( keyBlock
,  key
,  6 );  667                  num_to_bytes ( 0xffffffffffff ,  6 , ( uint8_t *)( keyBlock 
+  1  *  6 ));  668                  num_to_bytes ( 0x000000000000 ,  6 , ( uint8_t *)( keyBlock 
+  2  *  6 ));  669                  num_to_bytes ( 0xa0a1a2a3a4a5 ,  6 , ( uint8_t *)( keyBlock 
+  3  *  6 ));  670                  num_to_bytes ( 0xb0b1b2b3b4b5 ,  6 , ( uint8_t *)( keyBlock 
+  4  *  6 ));  671                  num_to_bytes ( 0xaabbccddeeff ,  6 , ( uint8_t *)( keyBlock 
+  5  *  6 ));  672                  num_to_bytes ( 0x4d3a99c351dd ,  6 , ( uint8_t *)( keyBlock 
+  6  *  6 ));  673                  num_to_bytes ( 0x1a982c7e459a ,  6 , ( uint8_t *)( keyBlock 
+  7  *  6 ));  674                  num_to_bytes ( 0xd3f7d3f7d3f7 ,  6 , ( uint8_t *)( keyBlock 
+  8  *  6 ));  675                  num_to_bytes ( 0x714c5c886e97 ,  6 , ( uint8_t *)( keyBlock 
+  9  *  6 ));  676                  num_to_bytes ( 0x587ee5f9350f ,  6 , ( uint8_t *)( keyBlock 
+  10  *  6 ));  677                  num_to_bytes ( 0xa0478cc39091 ,  6 , ( uint8_t *)( keyBlock 
+  11  *  6 ));  678                  num_to_bytes ( 0x533cb6c723f6 ,  6 , ( uint8_t *)( keyBlock 
+  12  *  6 ));  679                  num_to_bytes ( 0x8fd0a4f256e9 ,  6 , ( uint8_t *)( keyBlock 
+  13  *  6 ));  681                  PrintAndLog ( "Testing known keys. Sector count= %d " ,  SectorsCnt
);  682                  for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  683                          for  ( j 
=  0 ;  j 
<  2 ;  j
++) {  684                                  if  ( e_sector
[ i
]. foundKey
[ j
])  continue ;  686                                  res 
=  mfCheckKeys ( FirstBlockOfSector ( i
),  j
,  true ,  6 ,  keyBlock
, & key64
);  689                                          e_sector
[ i
]. Key
[ j
] =  key64
;  690                                          e_sector
[ i
]. foundKey
[ j
] =  1 ;  697                  PrintAndLog ( "nested..." );  698                  bool  calibrate 
=  true ;  699                  for  ( i 
=  0 ;  i 
<  NESTED_SECTOR_RETRY
;  i
++) {  700                          for  ( uint8_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  701                                  for  ( trgKeyType 
=  0 ;  trgKeyType 
<  2 ;  trgKeyType
++) {   702                                          if  ( e_sector
[ sectorNo
]. foundKey
[ trgKeyType
])  continue ;  703                                          PrintAndLog ( "-----------------------------------------------" );  704                                          int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  FirstBlockOfSector ( sectorNo
),  trgKeyType
,  keyBlock
,  calibrate
);  707                                                          case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  708                                                          case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  709                                                          case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  710                                                          default  :  PrintAndLog ( "Unknown Error. \n " );  720                                          key64 
=  bytes_to_num ( keyBlock
,  6 );  722                                                  PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  723                                                  e_sector
[ sectorNo
]. foundKey
[ trgKeyType
] =  1 ;  724                                                  e_sector
[ sectorNo
]. Key
[ trgKeyType
] =  key64
;  730                  printf ( "Time in nested:  %1 .3f ( %1 .3f sec per key) \n\n " , (( float ) clock () -  time1
)/ CLOCKS_PER_SEC
, (( float ) clock () -  time1
)/ iterations
/ CLOCKS_PER_SEC
);  732                  PrintAndLog ( "----------------------------------------------- \n Iterations count:  %d \n\n " ,  iterations
);  734                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  735                  PrintAndLog ( "|sec|key A           |res|key B           |res|" );  736                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  737                  for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  738                          PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |  %d  |   %0 12"  PRIx64 
"  |  %d  |" ,  i
,  739                                  e_sector
[ i
]. Key
[ 0 ],  e_sector
[ i
]. foundKey
[ 0 ],  e_sector
[ i
]. Key
[ 1 ],  e_sector
[ i
]. foundKey
[ 1 ]);  741                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  743                  // transfer them to the emulator  745                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  746                                  mfEmlGetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  747                                  if  ( e_sector
[ i
]. foundKey
[ 0 ])  748                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  keyBlock
);  749                                  if  ( e_sector
[ i
]. foundKey
[ 1 ])  750                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 , & keyBlock
[ 10 ]);  751                                  mfEmlSetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  756                  if  ( createDumpFile
) {  757                          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "wb" )) ==  NULL
) {   758                                  PrintAndLog ( "Could not create file dumpkeys.bin" );  762                          PrintAndLog ( "Printing keys to binary file dumpkeys.bin..." );  763                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  764                                  if  ( e_sector
[ i
]. foundKey
[ 0 ]){  765                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  tempkey
);  766                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  769                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  772                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  773                                  if  ( e_sector
[ i
]. foundKey
[ 1 ]){  774                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 ,  tempkey
);  775                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  778                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  789  int  CmdHF14AMfChk ( const char  * Cmd
)  792                  PrintAndLog ( "Usage:  hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d] [<key (12 hex symbols)>] [<dic (*.dic)>]" );  793                  PrintAndLog ( "          * - all sectors" );  794                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" );  795                  PrintAndLog ( "d - write keys to binary file \n " );  796                  PrintAndLog ( "t - write keys to emulator memory" );  797                  PrintAndLog ( "      sample: hf mf chk 0 A 1234567890ab keys.dic" );  798                  PrintAndLog ( "              hf mf chk *1 ? t" );  799                  PrintAndLog ( "              hf mf chk *1 ? d" );  804          char  filename
[ FILE_PATH_SIZE
]={ 0 };  806          uint8_t  * keyBlock 
=  NULL
, * p
;  807          uint8_t  stKeyBlock 
=  20 ;  813          uint8_t  SectorsCnt 
=  1 ;  817          int  transferToEml 
=  0 ;  818          int  createDumpFile 
=  0 ;  820          keyBlock 
=  calloc ( stKeyBlock
,  6 );  821          if  ( keyBlock 
==  NULL
)  return  1 ;  823          uint64_t  defaultKeys
[] =  825                  0xffffffffffff ,  // Default key (first key used by program if no user defined key)  826                  0x000000000000 ,  // Blank key  827                  0xa0a1a2a3a4a5 ,  // NFCForum MAD key  839          int  defaultKeysSize 
=  sizeof ( defaultKeys
) /  sizeof ( uint64_t );  841          for  ( int  defaultKeyCounter 
=  0 ;  defaultKeyCounter 
<  defaultKeysSize
;  defaultKeyCounter
++)  843                  num_to_bytes ( defaultKeys
[ defaultKeyCounter
],  6 , ( uint8_t *)( keyBlock 
+  defaultKeyCounter 
*  6 ));  846          if  ( param_getchar ( Cmd
,  0 )== '*' ) {  848                  switch ( param_getchar ( Cmd
+ 1 ,  0 )) {  849                          case  '0' :  SectorsCnt 
=   5 ;  break ;  850                          case  '1' :  SectorsCnt 
=  16 ;  break ;  851                          case  '2' :  SectorsCnt 
=  32 ;  break ;  852                          case  '4' :  SectorsCnt 
=  40 ;  break ;  853                          default :   SectorsCnt 
=  16 ;  857                  blockNo 
=  param_get8 ( Cmd
,  0 );  859          ctmp 
=  param_getchar ( Cmd
,  1 );  871                  PrintAndLog ( "Key type must be A , B or ?" );  875          ctmp 
=  param_getchar ( Cmd
,  2 );  876          if               ( ctmp 
==  't'  ||  ctmp 
==  'T' )  transferToEml 
=  1 ;  877          else if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  createDumpFile 
=  1 ;  879          for  ( i 
=  transferToEml 
||  createDumpFile
;  param_getchar ( Cmd
,  2  +  i
);  i
++) {  880                  if  (! param_gethex ( Cmd
,  2  +  i
,  keyBlock 
+  6  *  keycnt
,  12 )) {  881                          if  (  stKeyBlock 
-  keycnt 
<  2 ) {  882                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 ));  884                                          PrintAndLog ( "Cannot allocate memory for Keys" );  890                          PrintAndLog ( "chk key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
,  891                          ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ],  892                          ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 );  896                          if  (  param_getstr ( Cmd
,  2  +  i
, filename
) >=  FILE_PATH_SIZE 
) {  897                                  PrintAndLog ( "File name too long" );  902                          if  ( ( f 
=  fopen (  filename 
,  "r" )) ) {  903                                  while (  fgets ( buf
,  sizeof ( buf
),  f
) ){  904                                          if  ( strlen ( buf
) <  12  ||  buf
[ 11 ] ==  ' \n ' )  907                                          while  ( fgetc ( f
) !=  ' \n '  && ! feof ( f
)) ;   //goto next line  909                                          if (  buf
[ 0 ]== '#'  )  continue ;      //The line start with # is comment, skip  911                                          if  (! isxdigit ( buf
[ 0 ])){  912                                                  PrintAndLog ( "File content error. ' %s ' must include 12 HEX symbols" , buf
);  918                                          if  (  stKeyBlock 
-  keycnt 
<  2 ) {  919                                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 ));  921                                                          PrintAndLog ( "Cannot allocate memory for defKeys" );  927                                          memset ( keyBlock 
+  6  *  keycnt
,  0 ,  6 );  928                                          num_to_bytes ( strtoll ( buf
,  NULL
,  16 ),  6 ,  keyBlock 
+  6 * keycnt
);  929                                          PrintAndLog ( "chk custom key[ %2 d]  %0 12"  PRIx64 
,  keycnt
,  bytes_to_num ( keyBlock 
+  6 * keycnt
,  6 ));  931                                          memset ( buf
,  0 ,  sizeof ( buf
));  935                                  PrintAndLog ( "File:  %s : not found or locked." ,  filename
);  944                  PrintAndLog ( "No key specified, trying default keys" );  945                  for  (; keycnt 
<  defaultKeysSize
;  keycnt
++)  946                          PrintAndLog ( "chk default key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
,  947                                  ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ],  948                                  ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 );  951          // initialize storage for found keys  952          bool  validKey
[ 2 ][ 40 ];  953          uint8_t  foundKey
[ 2 ][ 40 ][ 6 ];  954          for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) {  955                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  956                          validKey
[ t
][ sectorNo
] =  false ;  957                          for  ( uint16_t  i 
=  0 ;  i 
<  6 ;  i
++) {  958                                  foundKey
[ t
][ sectorNo
][ i
] =  0xff ;  963          for  (  int  t 
= ! keyType
;  t 
<  2 ;  keyType
== 2 ?( t
++):( t
= 2 ) ) {  965                  for  ( int  i 
=  0 ;  i 
<  SectorsCnt
; ++ i
) {  966                          PrintAndLog ( "--sector: %2 d, block: %3 d, key type: %C , key count: %2 d " ,  i
,  b
,  t
? 'B' : 'A' ,  keycnt
);  967                          uint32_t  max_keys 
=  keycnt
> USB_CMD_DATA_SIZE
/ 6 ? USB_CMD_DATA_SIZE
/ 6 : keycnt
;  968                          for  ( uint32_t  c 
=  0 ;  c 
<  keycnt
;  c
+= max_keys
) {  969                                  uint32_t  size 
=  keycnt
- c
> max_keys
? max_keys
: keycnt
- c
;  970                                  res 
=  mfCheckKeys ( b
,  t
,  true ,  size
, & keyBlock
[ 6 * c
], & key64
);  973                                                  PrintAndLog ( "Found valid key:[ %0 12"  PRIx64 
"]" , key64
);  974                                                  num_to_bytes ( key64
,  6 ,  foundKey
[ t
][ i
]);  975                                                  validKey
[ t
][ i
] =  true ;  978                                          PrintAndLog ( "Command execute timeout" );  981                          b
< 127 ?( b
+= 4 ):( b
+= 16 );     987                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  988                          if  ( validKey
[ 0 ][ sectorNo
] ||  validKey
[ 1 ][ sectorNo
]) {  989                                  mfEmlGetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 );  990                                  for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) {  991                                          if  ( validKey
[ t
][ sectorNo
]) {  992                                                  memcpy ( block 
+  t
* 10 ,  foundKey
[ t
][ sectorNo
],  6 );  995                                  mfEmlSetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 );  998                  PrintAndLog ( "Found keys have been transferred to the emulator memory" ); 1001          if  ( createDumpFile
) { 1002                  FILE  * fkeys 
=  fopen ( "dumpkeys.bin" , "wb" ); 1003                  if  ( fkeys 
==  NULL
) {  1004                          PrintAndLog ( "Could not create file dumpkeys.bin" ); 1008                  for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) { 1009                          fwrite ( foundKey
[ t
],  1 ,  6 * SectorsCnt
,  fkeys
); 1012                  PrintAndLog ( "Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys." ); 1020  void  readerAttack ( nonces_t ar_resp
[],  bool  setEmulatorMem
,  bool  doStandardAttack
) { 1021          #define ATTACK_KEY_COUNT 8  // keep same as define in iso14443a.c -> Mifare1ksim() 1027          st_t sector_trailer
[ ATTACK_KEY_COUNT
]; 1028          memset ( sector_trailer
,  0x00 ,  sizeof ( sector_trailer
)); 1030          uint8_t  stSector
[ ATTACK_KEY_COUNT
]; 1031          memset ( stSector
,  0x00 ,  sizeof ( stSector
)); 1032          uint8_t  key_cnt
[ ATTACK_KEY_COUNT
]; 1033          memset ( key_cnt
,  0x00 ,  sizeof ( key_cnt
)); 1035          for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) { 1036                  if  ( ar_resp
[ i
]. ar2 
>  0 ) { 1037                          //PrintAndLog("DEBUG: Trying sector %d, cuid %08x, nt %08x, ar %08x, nr %08x, ar2 %08x, nr2 %08x",ar_resp[i].sector, ar_resp[i].cuid,ar_resp[i].nonce,ar_resp[i].ar,ar_resp[i].nr,ar_resp[i].ar2,ar_resp[i].nr2); 1038                          if  ( doStandardAttack 
&&  mfkey32 ( ar_resp
[ i
], & key
)) { 1039                                  PrintAndLog ( "  Found Key %s  for sector  %0 2d: [ %0 4x %0 8x]" , ( ar_resp
[ i
]. keytype
) ?  "B"  :  "A" ,  ar_resp
[ i
]. sector
, ( uint32_t ) ( key
>> 32 ), ( uint32_t ) ( key 
& 0xFFFFFFFF )); 1041                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) { 1042                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== ar_resp
[ i
]. sector
) { 1043                                                  if  ( ar_resp
[ i
]. keytype
== 0 ) { 1045                                                          sector_trailer
[ ii
]. keyA 
=  key
; 1046                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
; 1051                                                          sector_trailer
[ ii
]. keyB 
=  key
; 1052                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
; 1058                          }  else if  ( tryMfk32_moebius ( ar_resp
[ i
+ ATTACK_KEY_COUNT
], & key
)) { 1059                                  uint8_t  sectorNum 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. sector
; 1060                                  uint8_t  keyType 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. keytype
; 1062                                  PrintAndLog ( "M-Found Key %s  for sector  %0 2d: [ %0 12"  PRIx64 
"]" 1063                                          ,  keyType 
?  "B"  :  "A" 1068                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) { 1069                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== sectorNum
) { 1072                                                          sector_trailer
[ ii
]. keyA 
=  key
; 1073                                                          stSector
[ ii
] =  sectorNum
; 1078                                                          sector_trailer
[ ii
]. keyB 
=  key
; 1079                                                          stSector
[ ii
] =  sectorNum
; 1089          //set emulator memory for keys 1090          if  ( setEmulatorMem
) { 1091                  for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) { 1093                                  uint8_t  memBlock
[ 16 ]; 1094                                  memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1096                                  memset ( cmd1
, 0x00 , sizeof ( cmd1
)); 1097                                  snprintf ( cmd1
, sizeof ( cmd1
), " %0 4x %0 8xFF078069 %0 4x %0 8x" ,( uint32_t ) ( sector_trailer
[ i
]. keyA
>> 32 ), ( uint32_t ) ( sector_trailer
[ i
]. keyA 
& 0xFFFFFFFF ),( uint32_t ) ( sector_trailer
[ i
]. keyB
>> 32 ), ( uint32_t ) ( sector_trailer
[ i
]. keyB 
& 0xFFFFFFFF )); 1098                                  PrintAndLog ( "Setting Emulator Memory Block  %0 2d: [ %s ]" , stSector
[ i
]* 4 + 3 ,  cmd1
); 1099                                  if  ( param_gethex ( cmd1
,  0 ,  memBlock
,  32 )) { 1100                                          PrintAndLog ( "block data must include 32 HEX symbols" ); 1104                                  UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, {( stSector
[ i
]* 4 + 3 ),  1 ,  0 }}; 1105                                  memcpy ( c
. d
. asBytes
,  memBlock
,  16 ); 1106                                  clearCommandBuffer (); 1112          //un-comment to use as well moebius attack 1113          for (uint8_t i = ATTACK_KEY_COUNT; i<ATTACK_KEY_COUNT*2; i++) { 1114                  if (ar_resp[i].ar2 > 0) { 1115                          if (tryMfk32_moebius(ar_resp[i], &key)) { 1116                                  PrintAndLog("M-Found Key%s for sector %02d: [%04x%08x]", (ar_resp[i].keytype) ? "B" : "A", ar_resp[i].sector, (uint32_t) (key>>32), (uint32_t) (key &0xFFFFFFFF)); 1122  int  usage_hf14_mf1ksim ( void ) { 1123          PrintAndLog ( "Usage:  hf mf sim h u <uid (8, 14, or 20 hex symbols)> n <numreads> i x" ); 1124          PrintAndLog ( "options:" ); 1125          PrintAndLog ( "      h    this help" ); 1126          PrintAndLog ( "      u    (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used" ); 1127          PrintAndLog ( "      n    (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite" ); 1128          PrintAndLog ( "      i    (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted" ); 1129          PrintAndLog ( "      x    (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)" ); 1130          PrintAndLog ( "      e    (Optional) set keys found from 'reader attack' to emulator memory (implies x and i)" ); 1131          PrintAndLog ( "      f    (Optional) get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)" ); 1132          PrintAndLog ( "      r    (Optional) Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works." ); 1133          PrintAndLog ( "samples:" ); 1134          PrintAndLog ( "           hf mf sim u 0a0a0a0a" ); 1135          PrintAndLog ( "           hf mf sim u 11223344556677" ); 1136          PrintAndLog ( "           hf mf sim u 112233445566778899AA" ); 1137          PrintAndLog ( "           hf mf sim f uids.txt" ); 1138          PrintAndLog ( "           hf mf sim u 0a0a0a0a e" ); 1143  int  CmdHF14AMf1kSim ( const char  * Cmd
) { 1145          uint8_t  uid
[ 10 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 }; 1146          uint8_t  exitAfterNReads 
=  0 ; 1150          bool  setEmulatorMem 
=  false ; 1151          bool  attackFromFile 
=  false ; 1153          char  filename
[ FILE_PATH_SIZE
]; 1154          memset ( filename
,  0x00 ,  sizeof ( filename
)); 1159          bool  errors 
=  false ; 1161          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ) { 1162                  switch ( param_getchar ( Cmd
,  cmdp
)) { 1165                          setEmulatorMem 
=  true ; 1167                          flags 
|=  FLAG_INTERACTIVE
; 1168                          flags 
|=  FLAG_NR_AR_ATTACK
; 1173                          len 
=  param_getstr ( Cmd
,  cmdp
+ 1 ,  filename
); 1175                                  PrintAndLog ( "error no filename found" ); 1178                          attackFromFile 
=  true ; 1180                          flags 
|=  FLAG_INTERACTIVE
; 1181                          flags 
|=  FLAG_NR_AR_ATTACK
; 1186                          return  usage_hf14_mf1ksim (); 1189                          flags 
|=  FLAG_INTERACTIVE
; 1194                          exitAfterNReads 
=  param_get8 ( Cmd
,  pnr
+ 1 ); 1199                          flags 
|=  FLAG_RANDOM_NONCE
; 1204                          param_gethex_ex ( Cmd
,  cmdp
+ 1 ,  uid
, & uidlen
); 1206                                  case  20 :  flags 
=  FLAG_10B_UID_IN_DATA
;   break ;  //not complete 1207                                  case  14 :  flags 
=  FLAG_7B_UID_IN_DATA
;  break ; 1208                                  case   8 :  flags 
=  FLAG_4B_UID_IN_DATA
;  break ; 1209                                  default :  return  usage_hf14_mf1ksim (); 1215                          flags 
|=  FLAG_NR_AR_ATTACK
; 1219                          PrintAndLog ( "Unknown parameter ' %c '" ,  param_getchar ( Cmd
,  cmdp
)); 1226          if ( errors
)  return  usage_hf14_mf1ksim (); 1229          if  ( attackFromFile
) { 1232                  f 
=  fopen ( filename
,  "r" ); 1234                          PrintAndLog ( "File  %s  not found or locked" ,  filename
); 1237                  PrintAndLog ( "Loading file and simulating. Press keyboard to abort" ); 1238                  while (! feof ( f
) && ! ukbhit ()){ 1239                          memset ( buf
,  0 ,  sizeof ( buf
)); 1240                          memset ( uid
,  0 ,  sizeof ( uid
)); 1242                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) {                        1243                                  if  ( count 
>  0 )  break ; 1245                                  PrintAndLog ( "File reading error." ); 1249                          if (! strlen ( buf
) &&  feof ( f
))  break ; 1251                          uidlen 
=  strlen ( buf
)- 1 ; 1253                                  case  20 :  flags 
|=  FLAG_10B_UID_IN_DATA
;  break ;  //not complete 1254                                  case  14 :  flags 
|=  FLAG_7B_UID_IN_DATA
;  break ; 1255                                  case   8 :  flags 
|=  FLAG_4B_UID_IN_DATA
;  break ; 1257                                          PrintAndLog ( "uid in file wrong length at  %d  (length:  %d ) [ %s ]" , count
,  uidlen
,  buf
); 1262                          for  ( uint8_t  i 
=  0 ;  i 
<  uidlen
;  i 
+=  2 ) { 1263                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& uid
[ i 
/  2 ]); 1266                          PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) - press button to abort" , 1267                                          flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ): 1268                                                  flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ):  1269                                                          flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A" 1270                                          ,  exitAfterNReads
,  flags
,  flags
); 1272                          UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }}; 1273                          memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
)); 1274                          clearCommandBuffer (); 1277                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) { 1278                                  //We're waiting only 1.5 s at a time, otherwise we get the 1279                                  // annoying message about "Waiting for a response... " 1282                          nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ]; 1283                          memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
)); 1284                          // We can skip the standard attack if we have RANDOM_NONCE set. 1285                          readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
)); 1286                          if  (( bool ) resp
. arg
[ 1 ]) { 1287                                  PrintAndLog ( "Device button pressed - quitting" ); 1294          }  else  {  //not from file 1296                  PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) " , 1297                                  flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ): 1298                                          flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ):  1299                                                  flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A" 1300                                  ,  exitAfterNReads
,  flags
,  flags
); 1302                  UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }}; 1303                  memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
)); 1304                  clearCommandBuffer (); 1307                  if ( flags 
&  FLAG_INTERACTIVE
) { 1308                          PrintAndLog ( "Press pm3-button to abort simulation" ); 1309                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) { 1310                                  //We're waiting only 1.5 s at a time, otherwise we get the 1311                                  // annoying message about "Waiting for a response... " 1314                          if  ( flags 
&  FLAG_NR_AR_ATTACK
) { 1315                                  nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ]; 1316                                  memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
)); 1317                                  // We can skip the standard attack if we have RANDOM_NONCE set. 1318                                  readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
)); 1326  int  CmdHF14AMfDbg ( const char  * Cmd
) 1328          int  dbgMode 
=  param_get32ex ( Cmd
,  0 ,  0 ,  10 ); 1330                  PrintAndLog ( "Max debug mode parameter is 4  \n " ); 1333          if  ( strlen ( Cmd
) <  1  || ! param_getchar ( Cmd
,  0 ) ||  dbgMode 
>  4 ) { 1334                  PrintAndLog ( "Usage:  hf mf dbg  <debug level>" ); 1335                  PrintAndLog ( " 0 - no debug messages" ); 1336                  PrintAndLog ( " 1 - error messages" ); 1337                  PrintAndLog ( " 2 - plus information messages" ); 1338                  PrintAndLog ( " 3 - plus debug messages" ); 1339                  PrintAndLog ( " 4 - print even debug messages in timing critical functions" ); 1340                  PrintAndLog ( "     Note: this option therefore may cause malfunction itself" ); 1344    UsbCommand c 
= { CMD_MIFARE_SET_DBGMODE
, { dbgMode
,  0 ,  0 }}; 1350  int  CmdHF14AMfEGet ( const char  * Cmd
) 1352          uint8_t  blockNo 
=  0 ; 1353          uint8_t  data
[ 16 ] = { 0x00 }; 1355          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1356                  PrintAndLog ( "Usage:  hf mf eget <block number>" ); 1357                  PrintAndLog ( " sample: hf mf eget 0 " ); 1361          blockNo 
=  param_get8 ( Cmd
,  0 ); 1364          if  (! mfEmlGetMem ( data
,  blockNo
,  1 )) { 1365                  PrintAndLog ( "data[ %3 d]: %s " ,  blockNo
,  sprint_hex ( data
,  16 )); 1367                  PrintAndLog ( "Command execute timeout" ); 1373  int  CmdHF14AMfEClear ( const char  * Cmd
) 1375          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 1376                  PrintAndLog ( "Usage:  hf mf eclr" ); 1377                  PrintAndLog ( "It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF  \n " ); 1381    UsbCommand c 
= { CMD_MIFARE_EML_MEMCLR
, { 0 ,  0 ,  0 }}; 1387  int  CmdHF14AMfESet ( const char  * Cmd
) 1389          uint8_t  memBlock
[ 16 ]; 1390          uint8_t  blockNo 
=  0 ; 1392          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1394          if  ( strlen ( Cmd
) <  3  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1395                  PrintAndLog ( "Usage:  hf mf eset <block number> <block data (32 hex symbols)>" ); 1396                  PrintAndLog ( " sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f " ); 1400          blockNo 
=  param_get8 ( Cmd
,  0 ); 1402          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) { 1403                  PrintAndLog ( "block data must include 32 HEX symbols" ); 1408          UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, { blockNo
,  1 ,  0 }}; 1409          memcpy ( c
. d
. asBytes
,  memBlock
,  16 ); 1415  int  CmdHF14AMfELoad ( const char  * Cmd
) 1418          char  filename
[ FILE_PATH_SIZE
]; 1419          char  * fnameptr 
=  filename
; 1420          char  buf
[ 64 ] = { 0x00 }; 1421          uint8_t  buf8
[ 64 ] = { 0x00 }; 1422          int  i
,  len
,  blockNum
,  numBlocks
; 1423          int  nameParamNo 
=  1 ; 1425          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1427          if  (  ctmp 
==  'h'  ||  ctmp 
==  0x00 ) { 1428                  PrintAndLog ( "It loads emul dump from the file `filename.eml`" ); 1429                  PrintAndLog ( "Usage:  hf mf eload [card memory] <file name w/o `.eml`>" ); 1430                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1432                  PrintAndLog ( " sample: hf mf eload filename" ); 1433                  PrintAndLog ( "         hf mf eload 4 filename" ); 1438                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ; 1440                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ; 1441                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ; 1442                  case  '4'  :  numBlocks 
=  256 ;  break ; 1449          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
); 1451          if  ( len 
>  FILE_PATH_SIZE 
-  4 )  len 
=  FILE_PATH_SIZE 
-  4 ; 1455          sprintf ( fnameptr
,  ".eml" );  1458          f 
=  fopen ( filename
,  "r" ); 1460                  PrintAndLog ( "File  %s  not found or locked" ,  filename
); 1466                  memset ( buf
,  0 ,  sizeof ( buf
)); 1468                  if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) { 1470                          if  ( blockNum 
>=  numBlocks
)  break ; 1472                          PrintAndLog ( "File reading error." ); 1477                  if  ( strlen ( buf
) <  32 ){ 1478                          if ( strlen ( buf
) &&  feof ( f
)) 1480                          PrintAndLog ( "File content error. Block data must include 32 HEX symbols" ); 1485                  for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 ) { 1486                          sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]); 1489                  if  ( mfEmlSetMem ( buf8
,  blockNum
,  1 )) { 1490                          PrintAndLog ( "Cant set emul block:  %3 d" ,  blockNum
); 1497                  if  ( blockNum 
>=  numBlocks
)  break ; 1502          if  (( blockNum 
!=  numBlocks
)) { 1503                  PrintAndLog ( "File content error. Got  %d  must be  %d  blocks." , blockNum
,  numBlocks
); 1506          PrintAndLog ( "Loaded  %d  blocks from file:  %s " ,  blockNum
,  filename
); 1511  int  CmdHF14AMfESave ( const char  * Cmd
) 1514          char  filename
[ FILE_PATH_SIZE
]; 1515          char  *  fnameptr 
=  filename
; 1517          int  i
,  j
,  len
,  numBlocks
; 1518          int  nameParamNo 
=  1 ; 1520          memset ( filename
,  0 ,  sizeof ( filename
)); 1521          memset ( buf
,  0 ,  sizeof ( buf
)); 1523          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1525          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H' ) { 1526                  PrintAndLog ( "It saves emul dump into the file `filename.eml` or `cardID.eml`" ); 1527                  PrintAndLog ( " Usage:  hf mf esave [card memory] [file name w/o `.eml`]" ); 1528                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1530                  PrintAndLog ( " sample: hf mf esave " ); 1531                  PrintAndLog ( "         hf mf esave 4" ); 1532                  PrintAndLog ( "         hf mf esave 4 filename" ); 1537                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ; 1539                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ; 1540                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ; 1541                  case  '4'  :  numBlocks 
=  256 ;  break ; 1548          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
); 1550          if  ( len 
>  FILE_PATH_SIZE 
-  4 )  len 
=  FILE_PATH_SIZE 
-  4 ; 1552          // user supplied filename? 1554                  // get filename (UID from memory) 1555                  if  ( mfEmlGetMem ( buf
,  0 ,  1 )) { 1556                          PrintAndLog ( "Can \' t get UID from block:  %d " ,  0 ); 1557                          len 
=  sprintf ( fnameptr
,  "dump" ); 1561                          for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 ) 1562                                  sprintf ( fnameptr
,  " %0 2X" ,  buf
[ j
]); 1568          // add file extension 1569          sprintf ( fnameptr
,  ".eml" );  1572          f 
=  fopen ( filename
,  "w+" ); 1575                  PrintAndLog ( "Can't open file  %s  " ,  filename
); 1580          for  ( i 
=  0 ;  i 
<  numBlocks
;  i
++) { 1581                  if  ( mfEmlGetMem ( buf
,  i
,  1 )) { 1582                          PrintAndLog ( "Cant get block:  %d " ,  i
); 1585                  for  ( j 
=  0 ;  j 
<  16 ;  j
++) 1586                          fprintf ( f
,  " %0 2X" ,  buf
[ j
]);  1591          PrintAndLog ( "Saved  %d  blocks to file:  %s " ,  numBlocks
,  filename
); 1597  int  CmdHF14AMfECFill ( const char  * Cmd
) 1599          uint8_t  keyType 
=  0 ; 1600          uint8_t  numSectors 
=  16 ; 1602          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1603                  PrintAndLog ( "Usage:  hf mf ecfill <key A/B> [card memory]" ); 1604                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1606                  PrintAndLog ( "samples:  hf mf ecfill A" ); 1607                  PrintAndLog ( "          hf mf ecfill A 4" ); 1608                  PrintAndLog ( "Read card and transfer its data to emulator memory." ); 1609                  PrintAndLog ( "Keys must be laid in the emulator memory.  \n " ); 1613          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1614          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) { 1615                  PrintAndLog ( "Key type must be A or B" ); 1618          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  keyType 
=  1 ; 1620          ctmp 
=  param_getchar ( Cmd
,  1 ); 1622                  case  '0'  :  numSectors 
=  5 ;  break ; 1624                  case  '\0' :  numSectors 
=  16 ;  break ; 1625                  case  '2'  :  numSectors 
=  32 ;  break ; 1626                  case  '4'  :  numSectors 
=  40 ;  break ; 1627                  default :    numSectors 
=  16 ; 1630          printf ( "--params: numSectors:  %d , keyType: %d " ,  numSectors
,  keyType
); 1631          UsbCommand c 
= { CMD_MIFARE_EML_CARDLOAD
, { numSectors
,  keyType
,  0 }}; 1637  int  CmdHF14AMfEKeyPrn ( const char  * Cmd
) 1642          uint64_t  keyA
,  keyB
; 1644          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 1645                  PrintAndLog ( "It prints the keys loaded in the emulator memory" ); 1646                  PrintAndLog ( "Usage:  hf mf ekeyprn [card memory]" ); 1647                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1649                  PrintAndLog ( " sample: hf mf ekeyprn 1" ); 1653          char  cmdp 
=  param_getchar ( Cmd
,  0 ); 1656                  case  '0'  :  numSectors 
=  5 ;  break ; 1658                  case  '\0' :  numSectors 
=  16 ;  break ; 1659                  case  '2'  :  numSectors 
=  32 ;  break ; 1660                  case  '4'  :  numSectors 
=  40 ;  break ; 1661                  default :    numSectors 
=  16 ; 1664          PrintAndLog ( "|---|----------------|----------------|" ); 1665          PrintAndLog ( "|sec|key A           |key B           |" ); 1666          PrintAndLog ( "|---|----------------|----------------|" ); 1667          for  ( i 
=  0 ;  i 
<  numSectors
;  i
++) { 1668                  if  ( mfEmlGetMem ( data
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 )) { 1669                          PrintAndLog ( "error get block  %d " ,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ); 1672                  keyA 
=  bytes_to_num ( data
,  6 ); 1673                  keyB 
=  bytes_to_num ( data 
+  10 ,  6 ); 1674                  PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |   %0 12"  PRIx64 
"  |" ,  i
,  keyA
,  keyB
); 1676          PrintAndLog ( "|---|----------------|----------------|" ); 1682  int  CmdHF14AMfCSetUID ( const char  * Cmd
) 1684          uint8_t  wipeCard 
=  0 ; 1685          uint8_t  uid
[ 8 ] = { 0x00 }; 1686          uint8_t  oldUid
[ 8 ] = { 0x00 }; 1687          uint8_t  atqa
[ 2 ] = { 0x00 }; 1688          uint8_t  sak
[ 1 ] = { 0x00 }; 1689          uint8_t  atqaPresent 
=  1 ; 1694          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  argi
) ==  'h' ) { 1695                  PrintAndLog ( "Usage:  hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]" ); 1696                  PrintAndLog ( "sample:  hf mf csetuid 01020304" ); 1697                  PrintAndLog ( "sample:  hf mf csetuid 01020304 0004 08 w" ); 1698                  PrintAndLog ( "Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)" ); 1699                  PrintAndLog ( "If you also want to wipe the card then add 'w' at the end of the command line." ); 1703          if  ( param_getchar ( Cmd
,  argi
) &&  param_gethex ( Cmd
,  argi
,  uid
,  8 )) { 1704                  PrintAndLog ( "UID must include 8 HEX symbols" ); 1709          ctmp 
=  param_getchar ( Cmd
,  argi
); 1710          if  ( ctmp 
==  'w'  ||  ctmp 
==  'W' ) { 1716                  if  ( param_getchar ( Cmd
,  argi
)) { 1717                          if  ( param_gethex ( Cmd
,  argi
,  atqa
,  4 )) { 1718                                  PrintAndLog ( "ATQA must include 4 HEX symbols" ); 1722                          if  (! param_getchar ( Cmd
,  argi
) ||  param_gethex ( Cmd
,  argi
,  sak
,  2 )) { 1723                                  PrintAndLog ( "SAK must include 2 HEX symbols" ); 1732                  ctmp 
=  param_getchar ( Cmd
,  argi
); 1733                  if  ( ctmp 
==  'w'  ||  ctmp 
==  'W' ) { 1738          PrintAndLog ( "--wipe card: %s   uid: %s " , ( wipeCard
)? "YES" : "NO" ,  sprint_hex ( uid
,  4 )); 1740          res 
=  mfCSetUID ( uid
, ( atqaPresent
)? atqa
: NULL
, ( atqaPresent
)? sak
: NULL
,  oldUid
,  wipeCard
); 1742                          PrintAndLog ( "Can't set UID. error= %d " ,  res
); 1746          PrintAndLog ( "old UID: %s " ,  sprint_hex ( oldUid
,  4 )); 1747          PrintAndLog ( "new UID: %s " ,  sprint_hex ( uid
,  4 )); 1751  int  CmdHF14AMfCSetBlk ( const char  * Cmd
) 1753          uint8_t  memBlock
[ 16 ] = { 0x00 }; 1754          uint8_t  blockNo 
=  0 ; 1755          bool  wipeCard 
=  FALSE
; 1758          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1759                  PrintAndLog ( "Usage:  hf mf csetblk <block number> <block data (32 hex symbols)> [w]" ); 1760                  PrintAndLog ( "sample:  hf mf csetblk 1 01020304050607080910111213141516" ); 1761                  PrintAndLog ( "Set block data for magic Chinese card (only works with such cards)" ); 1762                  PrintAndLog ( "If you also want wipe the card then add 'w' at the end of the command line" ); 1766          blockNo 
=  param_get8 ( Cmd
,  0 ); 1768          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) { 1769                  PrintAndLog ( "block data must include 32 HEX symbols" ); 1773          char  ctmp 
=  param_getchar ( Cmd
,  2 ); 1774          wipeCard 
= ( ctmp 
==  'w'  ||  ctmp 
==  'W' ); 1775          PrintAndLog ( "--block number: %2 d data: %s " ,  blockNo
,  sprint_hex ( memBlock
,  16 )); 1777          res 
=  mfCSetBlock ( blockNo
,  memBlock
,  NULL
,  wipeCard
,  CSETBLOCK_SINGLE_OPER
); 1779                  PrintAndLog ( "Can't write block. error= %d " ,  res
); 1786  int  CmdHF14AMfCLoad ( const char  * Cmd
) 1789          char  filename
[ FILE_PATH_SIZE
] = { 0x00 }; 1790          char  *  fnameptr 
=  filename
; 1791          char  buf
[ 64 ] = { 0x00 }; 1792          uint8_t  buf8
[ 64 ] = { 0x00 }; 1793          uint8_t  fillFromEmulator 
=  0 ; 1794          int  i
,  len
,  blockNum
,  flags
= 0 ; 1796          if  ( param_getchar ( Cmd
,  0 ) ==  'h'  ||  param_getchar ( Cmd
,  0 )==  0x00 ) { 1797                  PrintAndLog ( "It loads magic Chinese card from the file `filename.eml`" ); 1798                  PrintAndLog ( "or from emulator memory (option `e`)" ); 1799                  PrintAndLog ( "Usage:  hf mf cload <file name w/o `.eml`>" ); 1800                  PrintAndLog ( "   or:  hf mf cload e " ); 1801                  PrintAndLog ( " sample: hf mf cload filename" ); 1805          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1806          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ; 1808          if  ( fillFromEmulator
) { 1809                  for  ( blockNum 
=  0 ;  blockNum 
<  16  *  4 ;  blockNum 
+=  1 ) { 1810                          if  ( mfEmlGetMem ( buf8
,  blockNum
,  1 )) { 1811                                  PrintAndLog ( "Cant get block:  %d " ,  blockNum
); 1814                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence 1815                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write 1816                          if  ( blockNum 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;              // Done. Magic Halt and switch off field. 1818                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) { 1819                                  PrintAndLog ( "Cant set magic card block:  %d " ,  blockNum
); 1826                  if  ( len 
>  FILE_PATH_SIZE 
-  4 )  len 
=  FILE_PATH_SIZE 
-  4 ; 1828                  memcpy ( filename
,  Cmd
,  len
); 1831                  sprintf ( fnameptr
,  ".eml" );  1834                  f 
=  fopen ( filename
,  "r" ); 1836                          PrintAndLog ( "File not found or locked." ); 1843                          memset ( buf
,  0 ,  sizeof ( buf
)); 1845                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) { 1847                                  PrintAndLog ( "File reading error." ); 1851                          if  ( strlen ( buf
) <  32 ) { 1852                                  if ( strlen ( buf
) &&  feof ( f
)) 1854                                  PrintAndLog ( "File content error. Block data must include 32 HEX symbols" ); 1858                          for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 ) 1859                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]); 1861                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence 1862                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write 1863                          if  ( blockNum 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;              // Done. Switch off field. 1865                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) { 1866                                  PrintAndLog ( "Can't set magic card block:  %d " ,  blockNum
); 1871                          if  ( blockNum 
>=  16  *  4 )  break ;   // magic card type - mifare 1K 1875                  if  ( blockNum 
!=  16  *  4  &&  blockNum 
!=  32  *  4  +  8  *  16 ){ 1876                          PrintAndLog ( "File content error. There must be 64 blocks" ); 1879                  PrintAndLog ( "Loaded from file:  %s " ,  filename
); 1885  int  CmdHF14AMfCGetBlk ( const char  * Cmd
) { 1886          uint8_t  memBlock
[ 16 ]; 1887          uint8_t  blockNo 
=  0 ; 1889          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1891          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1892                  PrintAndLog ( "Usage:  hf mf cgetblk <block number>" ); 1893                  PrintAndLog ( "sample:  hf mf cgetblk 1" ); 1894                  PrintAndLog ( "Get block data from magic Chinese card (only works with such cards) \n " ); 1898          blockNo 
=  param_get8 ( Cmd
,  0 ); 1900          PrintAndLog ( "--block number: %2 d " ,  blockNo
); 1902          res 
=  mfCGetBlock ( blockNo
,  memBlock
,  CSETBLOCK_SINGLE_OPER
); 1904                          PrintAndLog ( "Can't read block. error= %d " ,  res
); 1908          PrintAndLog ( "block data: %s " ,  sprint_hex ( memBlock
,  16 )); 1913  int  CmdHF14AMfCGetSc ( const char  * Cmd
) { 1914          uint8_t  memBlock
[ 16 ] = { 0x00 }; 1915          uint8_t  sectorNo 
=  0 ; 1918          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1919                  PrintAndLog ( "Usage:  hf mf cgetsc <sector number>" ); 1920                  PrintAndLog ( "sample:  hf mf cgetsc 0" ); 1921                  PrintAndLog ( "Get sector data from magic Chinese card (only works with such cards) \n " ); 1925          sectorNo 
=  param_get8 ( Cmd
,  0 ); 1926          if  ( sectorNo 
>  15 ) { 1927                  PrintAndLog ( "Sector number must be in [0..15] as in MIFARE classic." ); 1931          PrintAndLog ( "--sector number: %d  " ,  sectorNo
); 1933          flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 1934          for  ( i 
=  0 ;  i 
<  4 ;  i
++) { 1935                  if  ( i 
==  1 )  flags 
=  0 ; 1936                  if  ( i 
==  3 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 1938                  res 
=  mfCGetBlock ( sectorNo 
*  4  +  i
,  memBlock
,  flags
); 1940                          PrintAndLog ( "Can't read block.  %d  error= %d " ,  sectorNo 
*  4  +  i
,  res
); 1944                  PrintAndLog ( "block  %3 d data: %s " ,  sectorNo 
*  4  +  i
,  sprint_hex ( memBlock
,  16 )); 1950  int  CmdHF14AMfCSave ( const char  * Cmd
) { 1953          char  filename
[ FILE_PATH_SIZE
] = { 0x00 }; 1954          char  *  fnameptr 
=  filename
; 1955          uint8_t  fillFromEmulator 
=  0 ; 1956          uint8_t  buf
[ 64 ] = { 0x00 }; 1957          int  i
,  j
,  len
,  flags
; 1959          // memset(filename, 0, sizeof(filename)); 1960          // memset(buf, 0, sizeof(buf)); 1962          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 1963                  PrintAndLog ( "It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`" ); 1964                  PrintAndLog ( "or into emulator memory (option `e`)" ); 1965                  PrintAndLog ( "Usage:  hf mf esave [file name w/o `.eml`][e]" ); 1966                  PrintAndLog ( " sample: hf mf esave " ); 1967                  PrintAndLog ( "         hf mf esave filename" ); 1968                  PrintAndLog ( "         hf mf esave e  \n " ); 1972          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1973          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ; 1975          if  ( fillFromEmulator
) { 1976                  // put into emulator 1977                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 1978                  for  ( i 
=  0 ;  i 
<  16  *  4 ;  i
++) { 1979                          if  ( i 
==  1 )  flags 
=  0 ; 1980                          if  ( i 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 1982                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) { 1983                                  PrintAndLog ( "Cant get block:  %d " ,  i
); 1987                          if  ( mfEmlSetMem ( buf
,  i
,  1 )) { 1988                                  PrintAndLog ( "Cant set emul block:  %d " ,  i
); 1995                  if  ( len 
>  FILE_PATH_SIZE 
-  4 )  len 
=  FILE_PATH_SIZE 
-  4 ; 1999                          if  ( mfCGetBlock ( 0 ,  buf
,  CSETBLOCK_SINGLE_OPER
)) { 2000                                  PrintAndLog ( "Cant get block:  %d " ,  0 ); 2001                                  len 
=  sprintf ( fnameptr
,  "dump" ); 2005                                  for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 ) 2006                                          sprintf ( fnameptr
,  " %0 2x" ,  buf
[ j
]);  2009                          memcpy ( filename
,  Cmd
,  len
); 2013                  sprintf ( fnameptr
,  ".eml" );  2016                  f 
=  fopen ( filename
,  "w+" ); 2019                          PrintAndLog ( "File not found or locked." ); 2024                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 2025                  for  ( i 
=  0 ;  i 
<  16  *  4 ;  i
++) { 2026                          if  ( i 
==  1 )  flags 
=  0 ; 2027                          if  ( i 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 2029                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) { 2030                                  PrintAndLog ( "Cant get block:  %d " ,  i
); 2033                          for  ( j 
=  0 ;  j 
<  16 ;  j
++) 2034                                  fprintf ( f
,  " %0 2x" ,  buf
[ j
]);  2039                  PrintAndLog ( "Saved to file:  %s " ,  filename
); 2046  int  CmdHF14AMfSniff ( const char  * Cmd
){ 2048          bool  wantLogToFile 
=  0 ; 2049          bool  wantDecrypt 
=  0 ; 2050          //bool wantSaveToEml = 0; TODO 2051          bool  wantSaveToEmlFile 
=  0 ; 2061          uint8_t  atqa
[ 2 ] = { 0x00 }; 2064          uint8_t  * buf 
=  NULL
; 2065          uint16_t  bufsize 
=  0 ; 2066          uint8_t  * bufPtr 
=  NULL
; 2068          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 2069          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H'  ) { 2070                  PrintAndLog ( "It continuously gets data from the field and saves it to: log, emulator, emulator file." ); 2071                  PrintAndLog ( "You can specify:" ); 2072                  PrintAndLog ( "    l - save encrypted sequence to logfile `uid.log`" ); 2073                  PrintAndLog ( "    d - decrypt sequence and put it to log file `uid.log`" ); 2074                  PrintAndLog ( " n/a   e - decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory" ); 2075                  PrintAndLog ( "    f - decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`" ); 2076                  PrintAndLog ( "Usage:  hf mf sniff [l][d][e][f]" ); 2077                  PrintAndLog ( "  sample: hf mf sniff l d e" ); 2081          for  ( int  i 
=  0 ;  i 
<  4 ;  i
++) { 2082                  ctmp 
=  param_getchar ( Cmd
,  i
); 2083                  if  ( ctmp 
==  'l'  ||  ctmp 
==  'L' )  wantLogToFile 
=  true ; 2084                  if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  wantDecrypt 
=  true ; 2085                  //if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO 2086                  if  ( ctmp 
==  'f'  ||  ctmp 
==  'F' )  wantSaveToEmlFile 
=  true ; 2089          printf ( "------------------------------------------------------------------------- \n " ); 2090          printf ( "Executing command.  \n " ); 2091          printf ( "Press the key on the proxmark3 device to abort both proxmark3 and client. \n " ); 2092          printf ( "Press the key on pc keyboard to abort the client. \n " ); 2093          printf ( "------------------------------------------------------------------------- \n " ); 2095          UsbCommand c 
= { CMD_MIFARE_SNIFFER
, { 0 ,  0 ,  0 }}; 2096          clearCommandBuffer (); 2105                          printf ( " \n aborted via keyboard! \n " ); 2110                  if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 2000 )) { 2111                          res 
=  resp
. arg
[ 0 ] &  0xff ; 2112                          uint16_t  traceLen 
=  resp
. arg
[ 1 ]; 2115                          if  ( res 
==  0 )  return  0 ;                                          // we are done 2117                          if  ( res 
==  1 ) {                                                          // there is (more) data to be transferred 2118                                  if  ( pckNum 
==  0 ) {                                               // first packet, (re)allocate necessary buffer 2119                                          if  ( traceLen 
>  bufsize
) { 2121                                                  if  ( buf 
==  NULL
) {                               // not yet allocated 2122                                                          p 
=  malloc ( traceLen
); 2123                                                  }  else  {                                                 // need more memory 2124                                                          p 
=  realloc ( buf
,  traceLen
); 2127                                                          PrintAndLog ( "Cannot allocate memory for trace" ); 2135                                          memset ( buf
,  0x00 ,  traceLen
); 2137                                  memcpy ( bufPtr
,  resp
. d
. asBytes
,  len
); 2142                          if  ( res 
==  2 ) {                                                          // received all data, start displaying 2143                                  blockLen 
=  bufPtr 
-  buf
; 2146                                  PrintAndLog ( "received trace len:  %d  packages:  %d " ,  blockLen
,  pckNum
); 2147                                  while  ( bufPtr 
-  buf 
<  blockLen
) { 2148                                          bufPtr 
+=  6 ;                                             // skip (void) timing information 2149                                          len 
= *(( uint16_t  *) bufPtr
); 2157                                          if  (( len 
==  14 ) && ( bufPtr
[ 0 ] ==  0xff ) && ( bufPtr
[ 1 ] ==  0xff ) && ( bufPtr
[ 12 ] ==  0xff ) && ( bufPtr
[ 13 ] ==  0xff )) { 2158                                                  memcpy ( uid
,  bufPtr 
+  2 ,  7 ); 2159                                                  memcpy ( atqa
,  bufPtr 
+  2  +  7 ,  2 ); 2160                                                  uid_len 
= ( atqa
[ 0 ] &  0xC0 ) ==  0x40  ?  7  :  4 ; 2162                                                  PrintAndLog ( "tag select uid: %s  atqa:0x %0 2x %0 2x sak:0x %0 2x" ,  2163                                                          sprint_hex ( uid 
+ ( 7  -  uid_len
),  uid_len
), 2167                                                  if  ( wantLogToFile 
||  wantDecrypt
) { 2168                                                          FillFileNameByUID ( logHexFileName
,  uid 
+ ( 7  -  uid_len
),  ".log" ,  uid_len
); 2169                                                          AddLogCurrentDT ( logHexFileName
); 2172                                                          mfTraceInit ( uid
,  atqa
,  sak
,  wantSaveToEmlFile
); 2174                                                  PrintAndLog ( " %s ( %d ): %s " ,  isTag 
?  "TAG" : "RDR" ,  num
,  sprint_hex ( bufPtr
,  len
)); 2176                                                          AddLogHex ( logHexFileName
,  isTag 
?  "TAG: " : "RDR: " ,  bufPtr
,  len
); 2178                                                          mfTraceDecode ( bufPtr
,  len
,  wantSaveToEmlFile
); 2182                                          bufPtr 
+= (( len
- 1 )/ 8 + 1 );         // ignore parity 2193  //needs nt, ar, at, Data to decrypt 2194  int  CmdDecryptTraceCmds ( const char  * Cmd
){ 2197          param_gethex_ex ( Cmd
, 3 , data
,& len
); 2198          return  tryDecryptWord ( param_get32ex ( Cmd
, 0 , 0 , 16 ), param_get32ex ( Cmd
, 1 , 0 , 16 ), param_get32ex ( Cmd
, 2 , 0 , 16 ), data
, len
/ 2 ); 2201  static  command_t CommandTable
[] = 2203    { "help" ,               CmdHelp
,                                 1 ,  "This help" }, 2204    { "dbg" ,                CmdHF14AMfDbg
,                   0 ,  "Set default debug mode" }, 2205    { "rdbl" ,               CmdHF14AMfRdBl
,                  0 ,  "Read MIFARE classic block" }, 2206    { "rdsc" ,               CmdHF14AMfRdSc
,                  0 ,  "Read MIFARE classic sector" }, 2207    { "dump" ,               CmdHF14AMfDump
,                  0 ,  "Dump MIFARE classic tag to binary file" }, 2208    { "restore" ,    CmdHF14AMfRestore
,               0 ,  "Restore MIFARE classic binary file to BLANK tag" }, 2209    { "wrbl" ,               CmdHF14AMfWrBl
,                  0 ,  "Write MIFARE classic block" }, 2210    { "chk" ,                CmdHF14AMfChk
,                   0 ,  "Test block keys" }, 2211    { "mifare" ,     CmdHF14AMifare
,                  0 ,  "Read parity error messages." }, 2212    { "nested" ,     CmdHF14AMfNested
,                0 ,  "Test nested authentication" }, 2213    { "sniff" ,              CmdHF14AMfSniff
,                 0 ,  "Sniff card-reader communication" }, 2214    { "sim" ,                CmdHF14AMf1kSim
,                 0 ,  "Simulate MIFARE card" }, 2215    { "eclr" ,               CmdHF14AMfEClear
,                0 ,  "Clear simulator memory block" }, 2216    { "eget" ,               CmdHF14AMfEGet
,                  0 ,  "Get simulator memory block" }, 2217    { "eset" ,               CmdHF14AMfESet
,                  0 ,  "Set simulator memory block" }, 2218    { "eload" ,              CmdHF14AMfELoad
,                 0 ,  "Load from file emul dump" }, 2219    { "esave" ,              CmdHF14AMfESave
,                 0 ,  "Save to file emul dump" }, 2220    { "ecfill" ,     CmdHF14AMfECFill
,                0 ,  "Fill simulator memory with help of keys from simulator" }, 2221    { "ekeyprn" ,    CmdHF14AMfEKeyPrn
,               0 ,  "Print keys from simulator memory" }, 2222    { "csetuid" ,    CmdHF14AMfCSetUID
,               0 ,  "Set UID for magic Chinese card" }, 2223    { "csetblk" ,    CmdHF14AMfCSetBlk
,               0 ,  "Write block - Magic Chinese card" }, 2224    { "cgetblk" ,    CmdHF14AMfCGetBlk
,               0 ,  "Read block - Magic Chinese card" }, 2225    { "cgetsc" ,     CmdHF14AMfCGetSc
,                0 ,  "Read sector - Magic Chinese card" }, 2226    { "cload" ,              CmdHF14AMfCLoad
,                 0 ,  "Load dump into magic Chinese card" }, 2227    { "csave" ,              CmdHF14AMfCSave
,                 0 ,  "Save dump from magic Chinese card into file or emulator" }, 2228    { "decrypt" ,  CmdDecryptTraceCmds
, 1 ,  "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace" }, 2229    { NULL
,  NULL
,  0 ,  NULL
} 2232  int  CmdHFMF ( const char  * Cmd
) 2235          WaitForResponseTimeout ( CMD_ACK
, NULL
, 100 ); 2237    CmdsParse ( CommandTable
,  Cmd
); 2241  int  CmdHelp ( const char  * Cmd
) 2243    CmdsHelp ( CommandTable
);