]>
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  //-----------------------------------------------------------------------------   18  #include  "proxmark3.h"   20  #include  "cmdhfmfhard.h"   22  #include  "util_posix.h"   25  #include  "mifarehost.h"   29  #define NESTED_SECTOR_RETRY     10                       // how often we try mfested() until we give up   32  static int  CmdHelp ( const char  * Cmd
);   34  int  CmdHF14AMifare ( const char  * Cmd
)   38          isOK 
=  mfDarkside (& key
);   40                  case  - 1  :  PrintAndLog ( "Button pressed. Aborted." );  return  1 ;   41                  case  - 2  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)." );  return  1 ;   42                  case  - 3  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator is not predictable)." );  return  1 ;   43                  case  - 4  :  PrintAndLog ( "Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown" );   44                                    PrintAndLog ( "generating polynomial with 16 effective bits only, but shows unexpected behaviour." );  return  1 ;   45                  case  - 5  :  PrintAndLog ( "Aborted via keyboard." );   return  1 ;   46                  default  :  PrintAndLog ( "Found valid key: %0 12"  PRIx64 
" \n " ,  key
);   54  int  CmdHF14AMfWrBl ( const char  * Cmd
)   58          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };   59          uint8_t  bldata
[ 16 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 };   64                  PrintAndLog ( "Usage:  hf mf wrbl    <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>" );   65                  PrintAndLog ( "        sample: hf mf wrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F" );   69          blockNo 
=  param_get8 ( Cmd
,  0 );   70          cmdp 
=  param_getchar ( Cmd
,  1 );   72                  PrintAndLog ( "Key type must be A or B" );   75          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;   76          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {   77                  PrintAndLog ( "Key must include 12 HEX symbols" );   80          if  ( param_gethex ( Cmd
,  3 ,  bldata
,  32 )) {   81                  PrintAndLog ( "Block data must include 32 HEX symbols" );   84          PrintAndLog ( "--block no: %d , key type: %c , key: %s " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));   85          PrintAndLog ( "--data:  %s " ,  sprint_hex ( bldata
,  16 ));   87    UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { blockNo
,  keyType
,  0 }};   88          memcpy ( c
. d
. asBytes
,  key
,  6 );   89          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );   93          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {   94                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;   95                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);   97                  PrintAndLog ( "Command execute timeout" );  103  int  CmdHF14AMfRdBl ( const char  * Cmd
)  107          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  113                  PrintAndLog ( "Usage:  hf mf rdbl    <block number> <key A/B> <key (12 hex symbols)>" );  114                  PrintAndLog ( "        sample: hf mf rdbl 0 A FFFFFFFFFFFF " );  118          blockNo 
=  param_get8 ( Cmd
,  0 );  119          cmdp 
=  param_getchar ( Cmd
,  1 );  121                  PrintAndLog ( "Key type must be A or B" );  124          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  125          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  126                  PrintAndLog ( "Key must include 12 HEX symbols" );  129          PrintAndLog ( "--block no: %d , key type: %c , key: %s  " ,  blockNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  131    UsbCommand c 
= { CMD_MIFARE_READBL
, { blockNo
,  keyType
,  0 }};  132          memcpy ( c
. d
. asBytes
,  key
,  6 );  136          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  137                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  138                  uint8_t  * data 
=  resp
. d
. asBytes
;  141                          PrintAndLog ( "isOk: %0 2x data: %s " ,  isOK
,  sprint_hex ( data
,  16 ));  143                          PrintAndLog ( "isOk: %0 2x" ,  isOK
);  145                  PrintAndLog ( "Command execute timeout" );  151  int  CmdHF14AMfRdSc ( const char  * Cmd
)  154          uint8_t  sectorNo 
=  0 ;  156          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  158          uint8_t  * data  
=  NULL
;  162                  PrintAndLog ( "Usage:  hf mf rdsc    <sector number> <key A/B> <key (12 hex symbols)>" );  163                  PrintAndLog ( "        sample: hf mf rdsc 0 A FFFFFFFFFFFF " );  167          sectorNo 
=  param_get8 ( Cmd
,  0 );  169                  PrintAndLog ( "Sector number must be less than 40" );  172          cmdp 
=  param_getchar ( Cmd
,  1 );  173          if  ( cmdp 
!=  'a'  &&  cmdp 
!=  'A'  &&  cmdp 
!=  'b'  &&  cmdp 
!=  'B' ) {  174                  PrintAndLog ( "Key type must be A or B" );  177          if  ( cmdp 
!=  'A'  &&  cmdp 
!=  'a' )  keyType 
=  1 ;  178          if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  179                  PrintAndLog ( "Key must include 12 HEX symbols" );  182          PrintAndLog ( "--sector no: %d  key type: %c  key: %s  " ,  sectorNo
,  keyType
? 'B' : 'A' ,  sprint_hex ( key
,  6 ));  184          UsbCommand c 
= { CMD_MIFARE_READSC
, { sectorNo
,  keyType
,  0 }};  185          memcpy ( c
. d
. asBytes
,  key
,  6 );  190          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  191                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  192                  data  
=  resp
. d
. asBytes
;  194                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  196                          for  ( i 
=  0 ;  i 
< ( sectorNo
< 32 ? 3 : 15 );  i
++) {  197                                  PrintAndLog ( "data   :  %s " ,  sprint_hex ( data 
+  i 
*  16 ,  16 ));  199                          PrintAndLog ( "trailer:  %s " ,  sprint_hex ( data 
+ ( sectorNo
< 32 ? 3 : 15 ) *  16 ,  16 ));  202                  PrintAndLog ( "Command execute timeout" );  208  uint8_t  FirstBlockOfSector ( uint8_t  sectorNo
)  213                  return  32  *  4  + ( sectorNo 
-  32 ) *  16 ;  217  uint8_t  NumBlocksPerSector ( uint8_t  sectorNo
)  226  int  CmdHF14AMfDump ( const char  * Cmd
)  228          uint8_t  sectorNo
,  blockNo
;  232          uint8_t  rights
[ 40 ][ 4 ];  233          uint8_t  carddata
[ 256 ][ 16 ];  234          uint8_t  numSectors 
=  16 ;  241          char  cmdp 
=  param_getchar ( Cmd
,  0 );  243                  case  '0'  :  numSectors 
=  5 ;  break ;  245                  case  '\0' :  numSectors 
=  16 ;  break ;  246                  case  '2'  :  numSectors 
=  32 ;  break ;  247                  case  '4'  :  numSectors 
=  40 ;  break ;  248                  default :    numSectors 
=  16 ;  251          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  252                  PrintAndLog ( "Usage:   hf mf dump [card memory]" );  253                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  255                  PrintAndLog ( "Samples: hf mf dump" );  256                  PrintAndLog ( "         hf mf dump 4" );  260          if  (( fin 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  261                  PrintAndLog ( "Could not find file dumpkeys.bin" );  265          // Read keys A from file  266          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  267                  size_t  bytes_read 
=  fread ( keyA
[ sectorNo
],  1 ,  6 ,  fin
);  268                  if  ( bytes_read 
!=  6 ) {  269                          PrintAndLog ( "File reading error." );  275          // Read keys B from file  276          for  ( sectorNo
= 0 ;  sectorNo
< numSectors
;  sectorNo
++) {  277                  size_t  bytes_read 
=  fread ( keyB
[ sectorNo
],  1 ,  6 ,  fin
);  278                  if  ( bytes_read 
!=  6 ) {  279                          PrintAndLog ( "File reading error." );  287          PrintAndLog ( "|-----------------------------------------|" );  288          PrintAndLog ( "|------ Reading sector access bits...-----|" );  289          PrintAndLog ( "|-----------------------------------------|" );  291          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  292                  for  ( tries 
=  0 ;  tries 
<  3 ;  tries
++) {             293                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  0 ,  0 }};  294                          memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  297                          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  298                                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  299                                  uint8_t  * data  
=  resp
. d
. asBytes
;  301                                          rights
[ sectorNo
][ 0 ] = (( data
[ 7 ] &  0x10 )>> 2 ) | (( data
[ 8 ] &  0x1 )<< 1 ) | (( data
[ 8 ] &  0x10 )>> 4 );  // C1C2C3 for data area 0  302                                          rights
[ sectorNo
][ 1 ] = (( data
[ 7 ] &  0x20 )>> 3 ) | (( data
[ 8 ] &  0x2 )<< 0 ) | (( data
[ 8 ] &  0x20 )>> 5 );  // C1C2C3 for data area 1  303                                          rights
[ sectorNo
][ 2 ] = (( data
[ 7 ] &  0x40 )>> 4 ) | (( data
[ 8 ] &  0x4 )>> 1 ) | (( data
[ 8 ] &  0x40 )>> 6 );  // C1C2C3 for data area 2  304                                          rights
[ sectorNo
][ 3 ] = (( data
[ 7 ] &  0x80 )>> 5 ) | (( data
[ 8 ] &  0x8 )>> 2 ) | (( data
[ 8 ] &  0x80 )>> 7 );  // C1C2C3 for sector trailer  306                                  }  else if  ( tries 
==  2 ) {  // on last try set defaults  307                                          PrintAndLog ( "Could not get access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  308                                          rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  309                                          rights
[ sectorNo
][ 3 ] =  0x01 ;  312                                  PrintAndLog ( "Command execute timeout when trying to read access rights for sector  %2 d. Trying with defaults..." ,  sectorNo
);  313                                  rights
[ sectorNo
][ 0 ] =  rights
[ sectorNo
][ 1 ] =  rights
[ sectorNo
][ 2 ] =  0x00 ;  314                                  rights
[ sectorNo
][ 3 ] =  0x01 ;  319          PrintAndLog ( "|-----------------------------------------|" );  320          PrintAndLog ( "|----- Dumping all blocks to file... -----|" );  321          PrintAndLog ( "|-----------------------------------------|" );  324          for  ( sectorNo 
=  0 ;  isOK 
&&  sectorNo 
<  numSectors
;  sectorNo
++) {  325                  for  ( blockNo 
=  0 ;  isOK 
&&  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  326                          bool  received 
=  false ;  327                          for  ( tries 
=  0 ;  tries 
<  3 ;  tries
++) {                     328                                  if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. At least the Access Conditions can always be read with key A.   329                                          UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  330                                          memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  332                                          received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  333                                  }  else  {                                                                                                 // data block. Check if it can be read with key A or key B  334                                          uint8_t  data_area 
=  sectorNo
< 32 ? blockNo
: blockNo
/ 5 ;  335                                          if  (( rights
[ sectorNo
][ data_area
] ==  0x03 ) || ( rights
[ sectorNo
][ data_area
] ==  0x05 )) {    // only key B would work  336                                                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  1 ,  0 }};  337                                                  memcpy ( c
. d
. asBytes
,  keyB
[ sectorNo
],  6 );  339                                                  received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  340                                          }  else if  ( rights
[ sectorNo
][ data_area
] ==  0x07 ) {                                                                                // no key would work  342                                                  PrintAndLog ( "Access rights do not allow reading of sector  %2 d block  %3 d" ,  sectorNo
,  blockNo
);  344                                          }  else  {                                                                                                                                                                 // key A would work  345                                                  UsbCommand c 
= { CMD_MIFARE_READBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  0 ,  0 }};  346                                                  memcpy ( c
. d
. asBytes
,  keyA
[ sectorNo
],  6 );  348                                                  received 
=  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 );  352                                          isOK  
=  resp
. arg
[ 0 ] &  0xff ;  358                                  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  359                                  uint8_t  * data  
=  resp
. d
. asBytes
;  360                                  if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {               // sector trailer. Fill in the keys.  361                                          data
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  362                                          data
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  363                                          data
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  364                                          data
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  365                                          data
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  366                                          data
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  367                                          data
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  368                                          data
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  369                                          data
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  370                                          data
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  371                                          data
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  372                                          data
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  375                                          memcpy ( carddata
[ FirstBlockOfSector ( sectorNo
) +  blockNo
],  data
,  16 );  376                      PrintAndLog ( "Successfully read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  378                                          PrintAndLog ( "Could not read block  %2 d of sector  %2 d" ,  blockNo
,  sectorNo
);  384                                  PrintAndLog ( "Command execute timeout when trying to read block  %2 d of sector  %2 d." ,  blockNo
,  sectorNo
);  391                  if  (( fout 
=  fopen ( "dumpdata.bin" , "wb" )) ==  NULL
) {   392                          PrintAndLog ( "Could not create file name dumpdata.bin" );  395                  uint16_t  numblocks 
=  FirstBlockOfSector ( numSectors 
-  1 ) +  NumBlocksPerSector ( numSectors 
-  1 );  396                  fwrite ( carddata
,  1 ,  16 * numblocks
,  fout
);  398                  PrintAndLog ( "Dumped  %d  blocks ( %d  bytes) to file dumpdata.bin" ,  numblocks
,  16 * numblocks
);  404  int  CmdHF14AMfRestore ( const char  * Cmd
)  406          uint8_t  sectorNo
, blockNo
;  408          uint8_t  key
[ 6 ] = { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF };  409          uint8_t  bldata
[ 16 ] = { 0x00 };  417          char  cmdp 
=  param_getchar ( Cmd
,  0 );  419                  case  '0'  :  numSectors 
=  5 ;  break ;  421                  case  '\0' :  numSectors 
=  16 ;  break ;  422                  case  '2'  :  numSectors 
=  32 ;  break ;  423                  case  '4'  :  numSectors 
=  40 ;  break ;  424                  default :    numSectors 
=  16 ;  427          if  ( strlen ( Cmd
) >  1  ||  cmdp 
==  'h'  ||  cmdp 
==  'H' ) {  428                  PrintAndLog ( "Usage:   hf mf restore [card memory]" );  429                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" );  431                  PrintAndLog ( "Samples: hf mf restore" );  432                  PrintAndLog ( "         hf mf restore 4" );  436          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "rb" )) ==  NULL
) {  437                  PrintAndLog ( "Could not find file dumpkeys.bin" );  441          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  442                  size_t  bytes_read 
=  fread ( keyA
[ sectorNo
],  1 ,  6 ,  fkeys
);  443                  if  ( bytes_read 
!=  6 ) {  444                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  450          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  451                  size_t  bytes_read 
=  fread ( keyB
[ sectorNo
],  1 ,  6 ,  fkeys
);  452                  if  ( bytes_read 
!=  6 ) {  453                          PrintAndLog ( "File reading error (dumpkeys.bin)." );  461          if  (( fdump 
=  fopen ( "dumpdata.bin" , "rb" )) ==  NULL
) {  462                  PrintAndLog ( "Could not find file dumpdata.bin" );  465          PrintAndLog ( "Restoring dumpdata.bin to card" );  467          for  ( sectorNo 
=  0 ;  sectorNo 
<  numSectors
;  sectorNo
++) {  468                  for ( blockNo 
=  0 ;  blockNo 
<  NumBlocksPerSector ( sectorNo
);  blockNo
++) {  469                          UsbCommand c 
= { CMD_MIFARE_WRITEBL
, { FirstBlockOfSector ( sectorNo
) +  blockNo
,  keyType
,  0 }};  470                          memcpy ( c
. d
. asBytes
,  key
,  6 );  472                          size_t  bytes_read 
=  fread ( bldata
,  1 ,  16 ,  fdump
);  473                          if  ( bytes_read 
!=  16 ) {  474                                  PrintAndLog ( "File reading error (dumpdata.bin)." );  479                          if  ( blockNo 
==  NumBlocksPerSector ( sectorNo
) -  1 ) {       // sector trailer  480                                  bldata
[ 0 ]  = ( keyA
[ sectorNo
][ 0 ]);  481                                  bldata
[ 1 ]  = ( keyA
[ sectorNo
][ 1 ]);  482                                  bldata
[ 2 ]  = ( keyA
[ sectorNo
][ 2 ]);  483                                  bldata
[ 3 ]  = ( keyA
[ sectorNo
][ 3 ]);  484                                  bldata
[ 4 ]  = ( keyA
[ sectorNo
][ 4 ]);  485                                  bldata
[ 5 ]  = ( keyA
[ sectorNo
][ 5 ]);  486                                  bldata
[ 10 ] = ( keyB
[ sectorNo
][ 0 ]);  487                                  bldata
[ 11 ] = ( keyB
[ sectorNo
][ 1 ]);  488                                  bldata
[ 12 ] = ( keyB
[ sectorNo
][ 2 ]);  489                                  bldata
[ 13 ] = ( keyB
[ sectorNo
][ 3 ]);  490                                  bldata
[ 14 ] = ( keyB
[ sectorNo
][ 4 ]);  491                                  bldata
[ 15 ] = ( keyB
[ sectorNo
][ 5 ]);  494                          PrintAndLog ( "Writing to block  %3 d:  %s " ,  FirstBlockOfSector ( sectorNo
) +  blockNo
,  sprint_hex ( bldata
,  16 ));  496                          memcpy ( c
. d
. asBytes 
+  10 ,  bldata
,  16 );  500                          if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) {  501                                  uint8_t  isOK  
=  resp
. arg
[ 0 ] &  0xff ;  502                                  PrintAndLog ( "isOk: %0 2x" ,  isOK
);  504                                  PrintAndLog ( "Command execute timeout" );  520  int  CmdHF14AMfNested ( const char  * Cmd
)  522          int  i
,  j
,  res
,  iterations
;  523          sector_t 
* e_sector 
=  NULL
;  526          uint8_t  trgBlockNo 
=  0 ;  527          uint8_t  trgKeyType 
=  0 ;  528          uint8_t  SectorsCnt 
=  0 ;  529          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  530          uint8_t  keyBlock
[ 14 * 6 ];  532          bool  transferToEml 
=  false ;  534          bool  createDumpFile 
=  false ;  536          uint8_t  standart
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  537          uint8_t  tempkey
[ 6 ] = { 0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF ,  0xFF };  542                  PrintAndLog ( "Usage:" );  543                  PrintAndLog ( " all sectors:  hf mf nested  <card memory> <block number> <key A/B> <key (12 hex symbols)> [t,d]" );  544                  PrintAndLog ( " one sector:   hf mf nested  o <block number> <key A/B> <key (12 hex symbols)>" );  545                  PrintAndLog ( "               <target block number> <target key A/B> [t]" );  546                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" );  547                  PrintAndLog ( "t - transfer keys into emulator memory" );  548                  PrintAndLog ( "d - write keys to binary file" );  550                  PrintAndLog ( "      sample1: hf mf nested 1 0 A FFFFFFFFFFFF " );  551                  PrintAndLog ( "      sample2: hf mf nested 1 0 A FFFFFFFFFFFF t " );  552                  PrintAndLog ( "      sample3: hf mf nested 1 0 A FFFFFFFFFFFF d " );  553                  PrintAndLog ( "      sample4: hf mf nested o 0 A FFFFFFFFFFFF 4 A" );  557          cmdp 
=  param_getchar ( Cmd
,  0 );  558          blockNo 
=  param_get8 ( Cmd
,  1 );  559          ctmp 
=  param_getchar ( Cmd
,  2 );  561          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  562                  PrintAndLog ( "Key type must be A or B" );  566          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )   569          if  ( param_gethex ( Cmd
,  3 ,  key
,  12 )) {  570                  PrintAndLog ( "Key must include 12 HEX symbols" );  574          if  ( cmdp 
==  'o'  ||  cmdp 
==  'O' ) {  576                  trgBlockNo 
=  param_get8 ( Cmd
,  4 );  577                  ctmp 
=  param_getchar ( Cmd
,  5 );  578                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  579                          PrintAndLog ( "Target key type must be A or B" );  582                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )   587                          case  '0' :  SectorsCnt 
=  05 ;  break ;  588                          case  '1' :  SectorsCnt 
=  16 ;  break ;  589                          case  '2' :  SectorsCnt 
=  32 ;  break ;  590                          case  '4' :  SectorsCnt 
=  40 ;  break ;  591                          default :   SectorsCnt 
=  16 ;  595          ctmp 
=  param_getchar ( Cmd
,  4 );  596          if               ( ctmp 
==  't'  ||  ctmp 
==  'T' )  transferToEml 
=  true ;  597          else if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  createDumpFile 
=  true ;  599          ctmp 
=  param_getchar ( Cmd
,  6 );  600          transferToEml 
|= ( ctmp 
==  't'  ||  ctmp 
==  'T' );  601          transferToEml 
|= ( ctmp 
==  'd'  ||  ctmp 
==  'D' );  604                  PrintAndLog ( "--target block no: %3 d, target key type: %c  " ,  trgBlockNo
,  trgKeyType
? 'B' : 'A' );  605                  int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  trgBlockNo
,  trgKeyType
,  keyBlock
,  true );  608                                  case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  609                                  case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  610                                  case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  611                                  default  :  PrintAndLog ( "Unknown Error. \n " );  615                  key64 
=  bytes_to_num ( keyBlock
,  6 );  617                          PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  619                          // transfer key to the emulator  621                                  uint8_t  sectortrailer
;  622                                  if  ( trgBlockNo 
<  32 * 4 ) {         // 4 block sector  623                                          sectortrailer 
= ( trgBlockNo 
&  0x03 ) +  3 ;  624                                  }  else  {                                         // 16 block sector  625                                          sectortrailer 
= ( trgBlockNo 
&  0x0f ) +  15 ;  627                                  mfEmlGetMem ( keyBlock
,  sectortrailer
,  1 );  630                                          num_to_bytes ( key64
,  6 ,  keyBlock
);  632                                          num_to_bytes ( key64
,  6 , & keyBlock
[ 10 ]);  633                                  mfEmlSetMem ( keyBlock
,  sectortrailer
,  1 );                  636                          PrintAndLog ( "No valid key found" );  639          else  {  // ------------------------------------  multiple sectors working  641                  msclock1 
=  msclock ();  643                  e_sector 
=  calloc ( SectorsCnt
,  sizeof ( sector_t
));  644                  if  ( e_sector 
==  NULL
)  return  1 ;  646                  //test current key and additional standard keys first  647                  memcpy ( keyBlock
,  key
,  6 );  648                  num_to_bytes ( 0xffffffffffff ,  6 , ( uint8_t *)( keyBlock 
+  1  *  6 ));  649                  num_to_bytes ( 0x000000000000 ,  6 , ( uint8_t *)( keyBlock 
+  2  *  6 ));  650                  num_to_bytes ( 0xa0a1a2a3a4a5 ,  6 , ( uint8_t *)( keyBlock 
+  3  *  6 ));  651                  num_to_bytes ( 0xb0b1b2b3b4b5 ,  6 , ( uint8_t *)( keyBlock 
+  4  *  6 ));  652                  num_to_bytes ( 0xaabbccddeeff ,  6 , ( uint8_t *)( keyBlock 
+  5  *  6 ));  653                  num_to_bytes ( 0x4d3a99c351dd ,  6 , ( uint8_t *)( keyBlock 
+  6  *  6 ));  654                  num_to_bytes ( 0x1a982c7e459a ,  6 , ( uint8_t *)( keyBlock 
+  7  *  6 ));  655                  num_to_bytes ( 0xd3f7d3f7d3f7 ,  6 , ( uint8_t *)( keyBlock 
+  8  *  6 ));  656                  num_to_bytes ( 0x714c5c886e97 ,  6 , ( uint8_t *)( keyBlock 
+  9  *  6 ));  657                  num_to_bytes ( 0x587ee5f9350f ,  6 , ( uint8_t *)( keyBlock 
+  10  *  6 ));  658                  num_to_bytes ( 0xa0478cc39091 ,  6 , ( uint8_t *)( keyBlock 
+  11  *  6 ));  659                  num_to_bytes ( 0x533cb6c723f6 ,  6 , ( uint8_t *)( keyBlock 
+  12  *  6 ));  660                  num_to_bytes ( 0x8fd0a4f256e9 ,  6 , ( uint8_t *)( keyBlock 
+  13  *  6 ));  662                  PrintAndLog ( "Testing known keys. Sector count= %d " ,  SectorsCnt
);  663                  for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  664                          for  ( j 
=  0 ;  j 
<  2 ;  j
++) {  665                                  if  ( e_sector
[ i
]. foundKey
[ j
])  continue ;  667                                  res 
=  mfCheckKeys ( FirstBlockOfSector ( i
),  j
,  true ,  6 ,  keyBlock
, & key64
);  670                                          e_sector
[ i
]. Key
[ j
] =  key64
;  671                                          e_sector
[ i
]. foundKey
[ j
] =  1 ;  678                  PrintAndLog ( "nested..." );  679                  bool  calibrate 
=  true ;  680                  for  ( i 
=  0 ;  i 
<  NESTED_SECTOR_RETRY
;  i
++) {  681                          for  ( uint8_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) {  682                                  for  ( trgKeyType 
=  0 ;  trgKeyType 
<  2 ;  trgKeyType
++) {   683                                          if  ( e_sector
[ sectorNo
]. foundKey
[ trgKeyType
])  continue ;  684                                          PrintAndLog ( "-----------------------------------------------" );  685                                          int16_t  isOK 
=  mfnested ( blockNo
,  keyType
,  key
,  FirstBlockOfSector ( sectorNo
),  trgKeyType
,  keyBlock
,  calibrate
);  688                                                          case  - 1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  689                                                          case  - 2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  690                                                          case  - 3  :  PrintAndLog ( "Tag isn't vulnerable to Nested Attack (random numbers are not predictable). \n " );  break ;  691                                                          default  :  PrintAndLog ( "Unknown Error. \n " );  701                                          key64 
=  bytes_to_num ( keyBlock
,  6 );  703                                                  PrintAndLog ( "Found valid key: %0 12"  PRIx64
,  key64
);  704                                                  e_sector
[ sectorNo
]. foundKey
[ trgKeyType
] =  1 ;  705                                                  e_sector
[ sectorNo
]. Key
[ trgKeyType
] =  key64
;  711                  printf ( "Time in nested:  %1 .3f ( %1 .3f sec per key) \n\n " , (( float )( msclock () -  msclock1
))/ 1000.0 , (( float )( msclock () -  msclock1
))/ iterations
/ 1000.0 );  713                  PrintAndLog ( "----------------------------------------------- \n Iterations count:  %d \n\n " ,  iterations
);  715                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  716                  PrintAndLog ( "|sec|key A           |res|key B           |res|" );  717                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  718                  for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  719                          PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |  %d  |   %0 12"  PRIx64 
"  |  %d  |" ,  i
,  720                                  e_sector
[ i
]. Key
[ 0 ],  e_sector
[ i
]. foundKey
[ 0 ],  e_sector
[ i
]. Key
[ 1 ],  e_sector
[ i
]. foundKey
[ 1 ]);  722                  PrintAndLog ( "|---|----------------|---|----------------|---|" );  724                  // transfer them to the emulator  726                          for  ( i 
=  0 ;  i 
<  SectorsCnt
;  i
++) {  727                                  mfEmlGetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  728                                  if  ( e_sector
[ i
]. foundKey
[ 0 ])  729                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  keyBlock
);  730                                  if  ( e_sector
[ i
]. foundKey
[ 1 ])  731                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 , & keyBlock
[ 10 ]);  732                                  mfEmlSetMem ( keyBlock
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 );  737                  if  ( createDumpFile
) {  738                          if  (( fkeys 
=  fopen ( "dumpkeys.bin" , "wb" )) ==  NULL
) {   739                                  PrintAndLog ( "Could not create file dumpkeys.bin" );  743                          PrintAndLog ( "Printing keys to binary file dumpkeys.bin..." );  744                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  745                                  if  ( e_sector
[ i
]. foundKey
[ 0 ]){  746                                          num_to_bytes ( e_sector
[ i
]. Key
[ 0 ],  6 ,  tempkey
);  747                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  750                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  753                          for ( i
= 0 ;  i
< SectorsCnt
;  i
++) {  754                                  if  ( e_sector
[ i
]. foundKey
[ 1 ]){  755                                          num_to_bytes ( e_sector
[ i
]. Key
[ 1 ],  6 ,  tempkey
);  756                                          fwrite  (  tempkey
,  1 ,  6 ,  fkeys 
);  759                                          fwrite  ( & standart
,  1 ,  6 ,  fkeys 
);  771  int  CmdHF14AMfNestedHard ( const char  * Cmd
)  775          uint8_t  trgBlockNo 
=  0 ;  776          uint8_t  trgKeyType 
=  0 ;  777          uint8_t  key
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  778          uint8_t  trgkey
[ 6 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 };  781          ctmp 
=  param_getchar ( Cmd
,  0 );  783          if  ( ctmp 
!=  'R'  &&  ctmp 
!=  'r'  &&  ctmp 
!=  'T'  &&  ctmp 
!=  't'  &&  strlen ( Cmd
) <  20 ) {  784                  PrintAndLog ( "Usage:" );  785                  PrintAndLog ( "      hf mf hardnested <block number> <key A|B> <key (12 hex symbols)>" );  786                  PrintAndLog ( "                       <target block number> <target key A|B> [known target key (12 hex symbols)] [w] [s]" );  787                  PrintAndLog ( "  or  hf mf hardnested r [known target key]" );  789                  PrintAndLog ( "Options: " );  790                  PrintAndLog ( "      w: Acquire nonces and write them to binary file nonces.bin" );  791                  PrintAndLog ( "      s: Slower acquisition (required by some non standard cards)" );  792                  PrintAndLog ( "      r: Read nonces.bin and start attack" );  794                  PrintAndLog ( "      sample1: hf mf hardnested 0 A FFFFFFFFFFFF 4 A" );  795                  PrintAndLog ( "      sample2: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w" );  796                  PrintAndLog ( "      sample3: hf mf hardnested 0 A FFFFFFFFFFFF 4 A w s" );  797                  PrintAndLog ( "      sample4: hf mf hardnested r" );  799                  PrintAndLog ( "Add the known target key to check if it is present in the remaining key space:" );  800                  PrintAndLog ( "      sample5: hf mf hardnested 0 A A0A1A2A3A4A5 4 A FFFFFFFFFFFF" );  804          bool  know_target_key 
=  false ;  805          bool  nonce_file_read 
=  false ;  806          bool  nonce_file_write 
=  false ;  811          if  ( ctmp 
==  'R'  ||  ctmp 
==  'r' ) {  812                  nonce_file_read 
=  true ;  813                  if  (! param_gethex ( Cmd
,  1 ,  trgkey
,  12 )) {  814                          know_target_key 
=  true ;  816          }  else if  ( ctmp 
==  'T'  ||  ctmp 
==  't' ) {  817                  tests 
=  param_get32ex ( Cmd
,  1 ,  100 ,  10 );  818                  if  (! param_gethex ( Cmd
,  2 ,  trgkey
,  12 )) {  819                          know_target_key 
=  true ;  822                  blockNo 
=  param_get8 ( Cmd
,  0 );  823                  ctmp 
=  param_getchar ( Cmd
,  1 );  824                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  825                          PrintAndLog ( "Key type must be A or B" );  828                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' ) {   832                  if  ( param_gethex ( Cmd
,  2 ,  key
,  12 )) {  833                          PrintAndLog ( "Key must include 12 HEX symbols" );  837                  trgBlockNo 
=  param_get8 ( Cmd
,  3 );  838                  ctmp 
=  param_getchar ( Cmd
,  4 );  839                  if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) {  840                          PrintAndLog ( "Target key type must be A or B" );  843                  if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' ) {  849                  if  (! param_gethex ( Cmd
,  5 ,  trgkey
,  12 )) {  850                          know_target_key 
=  true ;  854                  while  (( ctmp 
=  param_getchar ( Cmd
,  i
))) {  855                          if  ( ctmp 
==  's'  ||  ctmp 
==  'S' ) {  857                          }  else if  ( ctmp 
==  'w'  ||  ctmp 
==  'W' ) {  858                                  nonce_file_write 
=  true ;  860                                  PrintAndLog ( "Possible options are w and/or s" );  867          PrintAndLog ( "--target block no: %3 d, target key type: %c , known target key: 0x %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x %s , file action:  %s , Slow:  %s , Tests:  %d  " ,   870                          trgkey
[ 0 ],  trgkey
[ 1 ],  trgkey
[ 2 ],  trgkey
[ 3 ],  trgkey
[ 4 ],  trgkey
[ 5 ],  871                          know_target_key
? "" : " (not set)" ,  872                          nonce_file_write
? "write" : nonce_file_read
? "read" : "none" ,  876          int16_t  isOK 
=  mfnestedhard ( blockNo
,  keyType
,  key
,  trgBlockNo
,  trgKeyType
,  know_target_key
? trgkey
: NULL
,  nonce_file_read
,  nonce_file_write
,  slow
,  tests
);  880                          case  1  :  PrintAndLog ( "Error: No response from Proxmark. \n " );  break ;  881                          case  2  :  PrintAndLog ( "Button pressed. Aborted. \n " );  break ;  891  int  CmdHF14AMfChk ( const char  * Cmd
)  894                  PrintAndLog ( "Usage:  hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d] [<key (12 hex symbols)>] [<dic (*.dic)>]" );  895                  PrintAndLog ( "          * - all sectors" );  896                  PrintAndLog ( "card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K" );  897                  PrintAndLog ( "d - write keys to binary file \n " );  898                  PrintAndLog ( "t - write keys to emulator memory" );  899                  PrintAndLog ( "      sample: hf mf chk 0 A 1234567890ab keys.dic" );  900                  PrintAndLog ( "              hf mf chk *1 ? t" );  901                  PrintAndLog ( "              hf mf chk *1 ? d" );  906          char  filename
[ FILE_PATH_SIZE
]={ 0 };  908          uint8_t  * keyBlock 
=  NULL
, * p
;  909          uint8_t  stKeyBlock 
=  20 ;  915          uint8_t  SectorsCnt 
=  1 ;  919          int  transferToEml 
=  0 ;  920          int  createDumpFile 
=  0 ;  922          keyBlock 
=  calloc ( stKeyBlock
,  6 );  923          if  ( keyBlock 
==  NULL
)  return  1 ;  925          uint64_t  defaultKeys
[] =  927                  0xffffffffffff ,  // Default key (first key used by program if no user defined key)  928                  0x000000000000 ,  // Blank key  929                  0xa0a1a2a3a4a5 ,  // NFCForum MAD key  941          int  defaultKeysSize 
=  sizeof ( defaultKeys
) /  sizeof ( uint64_t );  943          for  ( int  defaultKeyCounter 
=  0 ;  defaultKeyCounter 
<  defaultKeysSize
;  defaultKeyCounter
++)  945                  num_to_bytes ( defaultKeys
[ defaultKeyCounter
],  6 , ( uint8_t *)( keyBlock 
+  defaultKeyCounter 
*  6 ));  948          if  ( param_getchar ( Cmd
,  0 )== '*' ) {  950                  switch ( param_getchar ( Cmd
+ 1 ,  0 )) {  951                          case  '0' :  SectorsCnt 
=   5 ;  break ;  952                          case  '1' :  SectorsCnt 
=  16 ;  break ;  953                          case  '2' :  SectorsCnt 
=  32 ;  break ;  954                          case  '4' :  SectorsCnt 
=  40 ;  break ;  955                          default :   SectorsCnt 
=  16 ;  959                  blockNo 
=  param_get8 ( Cmd
,  0 );  961          ctmp 
=  param_getchar ( Cmd
,  1 );  973                  PrintAndLog ( "Key type must be A , B or ?" );  978          ctmp 
=  param_getchar ( Cmd
,  2 );  979          if               ( ctmp 
==  't'  ||  ctmp 
==  'T' )  transferToEml 
=  1 ;  980          else if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  createDumpFile 
=  1 ;  982          for  ( i 
=  transferToEml 
||  createDumpFile
;  param_getchar ( Cmd
,  2  +  i
);  i
++) {  983                  if  (! param_gethex ( Cmd
,  2  +  i
,  keyBlock 
+  6  *  keycnt
,  12 )) {  984                          if  (  stKeyBlock 
-  keycnt 
<  2 ) {  985                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 ));  987                                          PrintAndLog ( "Cannot allocate memory for Keys" );  993                          PrintAndLog ( "chk key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
,  994                          ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ],  995                          ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 );  999                          if  (  param_getstr ( Cmd
,  2  +  i
, filename
) >=  FILE_PATH_SIZE 
) { 1000                                  PrintAndLog ( "File name too long" ); 1005                          if  ( ( f 
=  fopen (  filename 
,  "r" )) ) { 1006                                  while (  fgets ( buf
,  sizeof ( buf
),  f
) ){ 1007                                          if  ( strlen ( buf
) <  12  ||  buf
[ 11 ] ==  ' \n ' ) 1010                                          while  ( fgetc ( f
) !=  ' \n '  && ! feof ( f
)) ;   //goto next line 1012                                          if (  buf
[ 0 ]== '#'  )  continue ;      //The line start with # is comment, skip 1014                                          if  (! isxdigit ( buf
[ 0 ])){ 1015                                                  PrintAndLog ( "File content error. ' %s ' must include 12 HEX symbols" , buf
); 1021                                          if  (  stKeyBlock 
-  keycnt 
<  2 ) { 1022                                                  p 
=  realloc ( keyBlock
,  6 *( stKeyBlock
+= 10 )); 1024                                                          PrintAndLog ( "Cannot allocate memory for defKeys" ); 1031                                          memset ( keyBlock 
+  6  *  keycnt
,  0 ,  6 ); 1032                                          num_to_bytes ( strtoll ( buf
,  NULL
,  16 ),  6 ,  keyBlock 
+  6 * keycnt
); 1033                                          PrintAndLog ( "chk custom key[ %2 d]  %0 12"  PRIx64 
,  keycnt
,  bytes_to_num ( keyBlock 
+  6 * keycnt
,  6 )); 1035                                          memset ( buf
,  0 ,  sizeof ( buf
)); 1039                                  PrintAndLog ( "File:  %s : not found or locked." ,  filename
); 1048                  PrintAndLog ( "No key specified, trying default keys" ); 1049                  for  (; keycnt 
<  defaultKeysSize
;  keycnt
++) 1050                          PrintAndLog ( "chk default key[ %2 d]  %0 2x %0 2x %0 2x %0 2x %0 2x %0 2x" ,  keycnt
, 1051                                  ( keyBlock 
+  6 * keycnt
)[ 0 ],( keyBlock 
+  6 * keycnt
)[ 1 ], ( keyBlock 
+  6 * keycnt
)[ 2 ], 1052                                  ( keyBlock 
+  6 * keycnt
)[ 3 ], ( keyBlock 
+  6 * keycnt
)[ 4 ],     ( keyBlock 
+  6 * keycnt
)[ 5 ],  6 ); 1055          // initialize storage for found keys 1056          bool  validKey
[ 2 ][ 40 ]; 1057          uint8_t  foundKey
[ 2 ][ 40 ][ 6 ]; 1058          for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) { 1059                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) { 1060                          validKey
[ t
][ sectorNo
] =  false ; 1061                          for  ( uint16_t  i 
=  0 ;  i 
<  6 ;  i
++) { 1062                                  foundKey
[ t
][ sectorNo
][ i
] =  0xff ; 1067          for  (  int  t 
= ! keyType
;  t 
<  2 ;  keyType
== 2 ?( t
++):( t
= 2 ) ) { 1069                  for  ( int  i 
=  0 ;  i 
<  SectorsCnt
; ++ i
) { 1070                          PrintAndLog ( "--sector: %2 d, block: %3 d, key type: %C , key count: %2 d " ,  i
,  b
,  t
? 'B' : 'A' ,  keycnt
); 1071                          uint32_t  max_keys 
=  keycnt
> USB_CMD_DATA_SIZE
/ 6 ? USB_CMD_DATA_SIZE
/ 6 : keycnt
; 1072                          for  ( uint32_t  c 
=  0 ;  c 
<  keycnt
;  c
+= max_keys
) { 1073                                  uint32_t  size 
=  keycnt
- c
> max_keys
? max_keys
: keycnt
- c
; 1074                                  res 
=  mfCheckKeys ( b
,  t
,  true ,  size
, & keyBlock
[ 6 * c
], & key64
); 1077                                                  PrintAndLog ( "Found valid key:[ %0 12"  PRIx64 
"]" , key64
); 1078                                                  num_to_bytes ( key64
,  6 ,  foundKey
[ t
][ i
]); 1079                                                  validKey
[ t
][ i
] =  true ; 1082                                          PrintAndLog ( "Command execute timeout" ); 1085                          b
< 127 ?( b
+= 4 ):( b
+= 16 );    1089          if  ( transferToEml
) { 1091                  for  ( uint16_t  sectorNo 
=  0 ;  sectorNo 
<  SectorsCnt
;  sectorNo
++) { 1092                          if  ( validKey
[ 0 ][ sectorNo
] ||  validKey
[ 1 ][ sectorNo
]) { 1093                                  mfEmlGetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 ); 1094                                  for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) { 1095                                          if  ( validKey
[ t
][ sectorNo
]) { 1096                                                  memcpy ( block 
+  t
* 10 ,  foundKey
[ t
][ sectorNo
],  6 ); 1099                                  mfEmlSetMem ( block
,  FirstBlockOfSector ( sectorNo
) +  NumBlocksPerSector ( sectorNo
) -  1 ,  1 ); 1102                  PrintAndLog ( "Found keys have been transferred to the emulator memory" ); 1105          if  ( createDumpFile
) { 1106                  FILE  * fkeys 
=  fopen ( "dumpkeys.bin" , "wb" ); 1107                  if  ( fkeys 
==  NULL
) {  1108                          PrintAndLog ( "Could not create file dumpkeys.bin" ); 1112                  for  ( uint16_t  t 
=  0 ;  t 
<  2 ;  t
++) { 1113                          fwrite ( foundKey
[ t
],  1 ,  6 * SectorsCnt
,  fkeys
); 1116                  PrintAndLog ( "Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys." ); 1124  void  readerAttack ( nonces_t ar_resp
[],  bool  setEmulatorMem
,  bool  doStandardAttack
) { 1125          #define ATTACK_KEY_COUNT 7  // keep same as define in iso14443a.c -> Mifare1ksim() 1126  // cannot be more than 7 or it will overrun c.d.asBytes(512) 1132          st_t sector_trailer
[ ATTACK_KEY_COUNT
]; 1133          memset ( sector_trailer
,  0x00 ,  sizeof ( sector_trailer
)); 1135          uint8_t  stSector
[ ATTACK_KEY_COUNT
]; 1136          memset ( stSector
,  0x00 ,  sizeof ( stSector
)); 1137          uint8_t  key_cnt
[ ATTACK_KEY_COUNT
]; 1138          memset ( key_cnt
,  0x00 ,  sizeof ( key_cnt
)); 1140          for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) { 1141                  if  ( ar_resp
[ i
]. ar2 
>  0 ) { 1142                          //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); 1143                          if  ( doStandardAttack 
&&  mfkey32 ( ar_resp
[ i
], & key
)) { 1144                                  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 )); 1146                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) { 1147                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== ar_resp
[ i
]. sector
) { 1148                                                  if  ( ar_resp
[ i
]. keytype
== 0 ) { 1150                                                          sector_trailer
[ ii
]. keyA 
=  key
; 1151                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
; 1156                                                          sector_trailer
[ ii
]. keyB 
=  key
; 1157                                                          stSector
[ ii
] =  ar_resp
[ i
]. sector
; 1163                          }  else if  ( mfkey32_moebius ( ar_resp
[ i
+ ATTACK_KEY_COUNT
], & key
)) { 1164                                  uint8_t  sectorNum 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. sector
; 1165                                  uint8_t  keyType 
=  ar_resp
[ i
+ ATTACK_KEY_COUNT
]. keytype
; 1167                                  PrintAndLog ( "M-Found Key %s  for sector  %0 2d: [ %0 12"  PRIx64 
"]" 1168                                          ,  keyType 
?  "B"  :  "A" 1173                                  for  ( uint8_t  ii 
=  0 ;  ii
< ATTACK_KEY_COUNT
;  ii
++) { 1174                                          if  ( key_cnt
[ ii
]== 0  ||  stSector
[ ii
]== sectorNum
) { 1177                                                          sector_trailer
[ ii
]. keyA 
=  key
; 1178                                                          stSector
[ ii
] =  sectorNum
; 1183                                                          sector_trailer
[ ii
]. keyB 
=  key
; 1184                                                          stSector
[ ii
] =  sectorNum
; 1194          //set emulator memory for keys 1195          if  ( setEmulatorMem
) { 1196                  for  ( uint8_t  i 
=  0 ;  i
< ATTACK_KEY_COUNT
;  i
++) { 1198                                  uint8_t  memBlock
[ 16 ]; 1199                                  memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1201                                  memset ( cmd1
, 0x00 , sizeof ( cmd1
)); 1202                                  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 )); 1203                                  PrintAndLog ( "Setting Emulator Memory Block  %0 2d: [ %s ]" , stSector
[ i
]* 4 + 3 ,  cmd1
); 1204                                  if  ( param_gethex ( cmd1
,  0 ,  memBlock
,  32 )) { 1205                                          PrintAndLog ( "block data must include 32 HEX symbols" ); 1209                                  UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, {( stSector
[ i
]* 4 + 3 ),  1 ,  0 }}; 1210                                  memcpy ( c
. d
. asBytes
,  memBlock
,  16 ); 1211                                  clearCommandBuffer (); 1217          //un-comment to use as well moebius attack 1218          for (uint8_t i = ATTACK_KEY_COUNT; i<ATTACK_KEY_COUNT*2; i++) { 1219                  if (ar_resp[i].ar2 > 0) { 1220                          if (tryMfk32_moebius(ar_resp[i], &key)) { 1221                                  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)); 1227  int  usage_hf14_mf1ksim ( void ) { 1228          PrintAndLog ( "Usage:  hf mf sim h u <uid (8, 14, or 20 hex symbols)> n <numreads> i x" ); 1229          PrintAndLog ( "options:" ); 1230          PrintAndLog ( "      h    this help" ); 1231          PrintAndLog ( "      u    (Optional) UID 4,7 or 10 bytes. If not specified, the UID 4B from emulator memory will be used" ); 1232          PrintAndLog ( "      n    (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite" ); 1233          PrintAndLog ( "      i    (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted" ); 1234          PrintAndLog ( "      x    (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)" ); 1235          PrintAndLog ( "      e    (Optional) set keys found from 'reader attack' to emulator memory (implies x and i)" ); 1236          PrintAndLog ( "      f    (Optional) get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)" ); 1237          PrintAndLog ( "      r    (Optional) Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works." ); 1238          PrintAndLog ( "samples:" ); 1239          PrintAndLog ( "           hf mf sim u 0a0a0a0a" ); 1240          PrintAndLog ( "           hf mf sim u 11223344556677" ); 1241          PrintAndLog ( "           hf mf sim u 112233445566778899AA" ); 1242          PrintAndLog ( "           hf mf sim f uids.txt" ); 1243          PrintAndLog ( "           hf mf sim u 0a0a0a0a e" ); 1248  int  CmdHF14AMf1kSim ( const char  * Cmd
) { 1250          uint8_t  uid
[ 10 ] = { 0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 ,  0 }; 1251          uint8_t  exitAfterNReads 
=  0 ; 1255          bool  setEmulatorMem 
=  false ; 1256          bool  attackFromFile 
=  false ; 1258          char  filename
[ FILE_PATH_SIZE
]; 1259          memset ( filename
,  0x00 ,  sizeof ( filename
)); 1264          bool  errors 
=  false ; 1266          while ( param_getchar ( Cmd
,  cmdp
) !=  0x00 ) { 1267                  switch ( param_getchar ( Cmd
,  cmdp
)) { 1270                          setEmulatorMem 
=  true ; 1272                          flags 
|=  FLAG_INTERACTIVE
; 1273                          flags 
|=  FLAG_NR_AR_ATTACK
; 1278                          len 
=  param_getstr ( Cmd
,  cmdp
+ 1 ,  filename
); 1280                                  PrintAndLog ( "error no filename found" ); 1283                          attackFromFile 
=  true ; 1285                          flags 
|=  FLAG_INTERACTIVE
; 1286                          flags 
|=  FLAG_NR_AR_ATTACK
; 1291                          return  usage_hf14_mf1ksim (); 1294                          flags 
|=  FLAG_INTERACTIVE
; 1299                          exitAfterNReads 
=  param_get8 ( Cmd
,  pnr
+ 1 ); 1304                          flags 
|=  FLAG_RANDOM_NONCE
; 1309                          param_gethex_ex ( Cmd
,  cmdp
+ 1 ,  uid
, & uidlen
); 1311                                  case  20 :  flags 
=  FLAG_10B_UID_IN_DATA
;   break ;  //not complete 1312                                  case  14 :  flags 
=  FLAG_7B_UID_IN_DATA
;  break ; 1313                                  case   8 :  flags 
=  FLAG_4B_UID_IN_DATA
;  break ; 1314                                  default :  return  usage_hf14_mf1ksim (); 1320                          flags 
|=  FLAG_NR_AR_ATTACK
; 1324                          PrintAndLog ( "Unknown parameter ' %c '" ,  param_getchar ( Cmd
,  cmdp
)); 1331          if ( errors
)  return  usage_hf14_mf1ksim (); 1334          if  ( attackFromFile
) { 1337                  f 
=  fopen ( filename
,  "r" ); 1339                          PrintAndLog ( "File  %s  not found or locked" ,  filename
); 1342                  PrintAndLog ( "Loading file and simulating. Press keyboard to abort" ); 1343                  while (! feof ( f
) && ! ukbhit ()){ 1344                          memset ( buf
,  0 ,  sizeof ( buf
)); 1345                          memset ( uid
,  0 ,  sizeof ( uid
)); 1347                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) {                        1348                                  if  ( count 
>  0 )  break ; 1350                                  PrintAndLog ( "File reading error." ); 1354                          if (! strlen ( buf
) &&  feof ( f
))  break ; 1356                          uidlen 
=  strlen ( buf
)- 1 ; 1358                                  case  20 :  flags 
|=  FLAG_10B_UID_IN_DATA
;  break ;  //not complete 1359                                  case  14 :  flags 
|=  FLAG_7B_UID_IN_DATA
;  break ; 1360                                  case   8 :  flags 
|=  FLAG_4B_UID_IN_DATA
;  break ; 1362                                          PrintAndLog ( "uid in file wrong length at  %d  (length:  %d ) [ %s ]" , count
,  uidlen
,  buf
); 1367                          for  ( uint8_t  i 
=  0 ;  i 
<  uidlen
;  i 
+=  2 ) { 1368                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& uid
[ i 
/  2 ]); 1371                          PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) - press button to abort" , 1372                                          flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ): 1373                                                  flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ):  1374                                                          flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A" 1375                                          ,  exitAfterNReads
,  flags
,  flags
); 1377                          UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }}; 1378                          memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
)); 1379                          clearCommandBuffer (); 1382                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) { 1383                                  //We're waiting only 1.5 s at a time, otherwise we get the 1384                                  // annoying message about "Waiting for a response... " 1387                          nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ]; 1388                          memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
)); 1389                          // We can skip the standard attack if we have RANDOM_NONCE set. 1390                          readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
)); 1391                          if  (( bool ) resp
. arg
[ 1 ]) { 1392                                  PrintAndLog ( "Device button pressed - quitting" ); 1399          }  else  {  //not from file 1401                  PrintAndLog ( "mf 1k sim uid:  %s , numreads: %d , flags: %d  (0x %0 2x) " , 1402                                  flags 
&  FLAG_4B_UID_IN_DATA 
?  sprint_hex ( uid
, 4 ): 1403                                          flags 
&  FLAG_7B_UID_IN_DATA     
?  sprint_hex ( uid
, 7 ):  1404                                                  flags 
&  FLAG_10B_UID_IN_DATA 
?  sprint_hex ( uid
, 10 ):  "N/A" 1405                                  ,  exitAfterNReads
,  flags
,  flags
); 1407                  UsbCommand c 
= { CMD_SIMULATE_MIFARE_CARD
, { flags
,  exitAfterNReads
, 0 }}; 1408                  memcpy ( c
. d
. asBytes
,  uid
,  sizeof ( uid
)); 1409                  clearCommandBuffer (); 1412                  if ( flags 
&  FLAG_INTERACTIVE
) { 1413                          PrintAndLog ( "Press pm3-button to abort simulation" ); 1414                          while (!  WaitForResponseTimeout ( CMD_ACK
,& resp
, 1500 )) { 1415                                  //We're waiting only 1.5 s at a time, otherwise we get the 1416                                  // annoying message about "Waiting for a response... " 1419                          if  ( flags 
&  FLAG_NR_AR_ATTACK
) { 1420                                  nonces_t ar_resp
[ ATTACK_KEY_COUNT
* 2 ]; 1421                                  memcpy ( ar_resp
,  resp
. d
. asBytes
,  sizeof ( ar_resp
)); 1422                                  // We can skip the standard attack if we have RANDOM_NONCE set. 1423                                  readerAttack ( ar_resp
,  setEmulatorMem
, !( flags 
&  FLAG_RANDOM_NONCE
)); 1431  int  CmdHF14AMfDbg ( const char  * Cmd
) 1433          int  dbgMode 
=  param_get32ex ( Cmd
,  0 ,  0 ,  10 ); 1435                  PrintAndLog ( "Max debug mode parameter is 4  \n " ); 1438          if  ( strlen ( Cmd
) <  1  || ! param_getchar ( Cmd
,  0 ) ||  dbgMode 
>  4 ) { 1439                  PrintAndLog ( "Usage:  hf mf dbg  <debug level>" ); 1440                  PrintAndLog ( " 0 - no debug messages" ); 1441                  PrintAndLog ( " 1 - error messages" ); 1442                  PrintAndLog ( " 2 - plus information messages" ); 1443                  PrintAndLog ( " 3 - plus debug messages" ); 1444                  PrintAndLog ( " 4 - print even debug messages in timing critical functions" ); 1445                  PrintAndLog ( "     Note: this option therefore may cause malfunction itself" ); 1449    UsbCommand c 
= { CMD_MIFARE_SET_DBGMODE
, { dbgMode
,  0 ,  0 }}; 1455  int  CmdHF14AMfEGet ( const char  * Cmd
) 1457          uint8_t  blockNo 
=  0 ; 1458          uint8_t  data
[ 16 ] = { 0x00 }; 1460          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1461                  PrintAndLog ( "Usage:  hf mf eget <block number>" ); 1462                  PrintAndLog ( " sample: hf mf eget 0 " ); 1466          blockNo 
=  param_get8 ( Cmd
,  0 ); 1469          if  (! mfEmlGetMem ( data
,  blockNo
,  1 )) { 1470                  PrintAndLog ( "data[ %3 d]: %s " ,  blockNo
,  sprint_hex ( data
,  16 )); 1472                  PrintAndLog ( "Command execute timeout" ); 1478  int  CmdHF14AMfEClear ( const char  * Cmd
) 1480          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 1481                  PrintAndLog ( "Usage:  hf mf eclr" ); 1482                  PrintAndLog ( "It set card emulator memory to empty data blocks and key A/B FFFFFFFFFFFF  \n " ); 1486    UsbCommand c 
= { CMD_MIFARE_EML_MEMCLR
, { 0 ,  0 ,  0 }}; 1492  int  CmdHF14AMfESet ( const char  * Cmd
) 1494          uint8_t  memBlock
[ 16 ]; 1495          uint8_t  blockNo 
=  0 ; 1497          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1499          if  ( strlen ( Cmd
) <  3  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1500                  PrintAndLog ( "Usage:  hf mf eset <block number> <block data (32 hex symbols)>" ); 1501                  PrintAndLog ( " sample: hf mf eset 1 000102030405060708090a0b0c0d0e0f " ); 1505          blockNo 
=  param_get8 ( Cmd
,  0 ); 1507          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) { 1508                  PrintAndLog ( "block data must include 32 HEX symbols" ); 1513          UsbCommand c 
= { CMD_MIFARE_EML_MEMSET
, { blockNo
,  1 ,  0 }}; 1514          memcpy ( c
. d
. asBytes
,  memBlock
,  16 ); 1520  int  CmdHF14AMfELoad ( const char  * Cmd
) 1523          char  filename
[ FILE_PATH_SIZE
]; 1524          char  * fnameptr 
=  filename
; 1525          char  buf
[ 64 ] = { 0x00 }; 1526          uint8_t  buf8
[ 64 ] = { 0x00 }; 1527          int  i
,  len
,  blockNum
,  numBlocks
; 1528          int  nameParamNo 
=  1 ; 1530          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1532          if  (  ctmp 
==  'h'  ||  ctmp 
==  0x00 ) { 1533                  PrintAndLog ( "It loads emul dump from the file `filename.eml`" ); 1534                  PrintAndLog ( "Usage:  hf mf eload [card memory] <file name w/o `.eml`>" ); 1535                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1537                  PrintAndLog ( " sample: hf mf eload filename" ); 1538                  PrintAndLog ( "         hf mf eload 4 filename" ); 1543                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ; 1545                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ; 1546                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ; 1547                  case  '4'  :  numBlocks 
=  256 ;  break ; 1554          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
); 1556          if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 1560          sprintf ( fnameptr
,  ".eml" );  1563          f 
=  fopen ( filename
,  "r" ); 1565                  PrintAndLog ( "File  %s  not found or locked" ,  filename
); 1571                  memset ( buf
,  0 ,  sizeof ( buf
)); 1573                  if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) { 1575                          if  ( blockNum 
>=  numBlocks
)  break ; 1577                          PrintAndLog ( "File reading error." ); 1582                  if  ( strlen ( buf
) <  32 ){ 1583                          if ( strlen ( buf
) &&  feof ( f
)) 1585                          PrintAndLog ( "File content error. Block data must include 32 HEX symbols" ); 1590                  for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 ) { 1591                          sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]); 1594                  if  ( mfEmlSetMem ( buf8
,  blockNum
,  1 )) { 1595                          PrintAndLog ( "Cant set emul block:  %3 d" ,  blockNum
); 1602                  if  ( blockNum 
>=  numBlocks
)  break ; 1607          if  (( blockNum 
!=  numBlocks
)) { 1608                  PrintAndLog ( "File content error. Got  %d  must be  %d  blocks." , blockNum
,  numBlocks
); 1611          PrintAndLog ( "Loaded  %d  blocks from file:  %s " ,  blockNum
,  filename
); 1616  int  CmdHF14AMfESave ( const char  * Cmd
) 1619          char  filename
[ FILE_PATH_SIZE
]; 1620          char  *  fnameptr 
=  filename
; 1622          int  i
,  j
,  len
,  numBlocks
; 1623          int  nameParamNo 
=  1 ; 1625          memset ( filename
,  0 ,  sizeof ( filename
)); 1626          memset ( buf
,  0 ,  sizeof ( buf
)); 1628          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1630          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H' ) { 1631                  PrintAndLog ( "It saves emul dump into the file `filename.eml` or `cardID.eml`" ); 1632                  PrintAndLog ( " Usage:  hf mf esave [card memory] [file name w/o `.eml`]" ); 1633                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1635                  PrintAndLog ( " sample: hf mf esave " ); 1636                  PrintAndLog ( "         hf mf esave 4" ); 1637                  PrintAndLog ( "         hf mf esave 4 filename" ); 1642                  case  '0'  :  numBlocks 
=  5 * 4 ;  break ; 1644                  case  '\0' :  numBlocks 
=  16 * 4 ;  break ; 1645                  case  '2'  :  numBlocks 
=  32 * 4 ;  break ; 1646                  case  '4'  :  numBlocks 
=  256 ;  break ; 1653          len 
=  param_getstr ( Cmd
, nameParamNo
, filename
); 1655          if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 1657          // user supplied filename? 1659                  // get filename (UID from memory) 1660                  if  ( mfEmlGetMem ( buf
,  0 ,  1 )) { 1661                          PrintAndLog ( "Can \' t get UID from block:  %d " ,  0 ); 1662                          len 
=  sprintf ( fnameptr
,  "dump" ); 1666                          for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 ) 1667                                  sprintf ( fnameptr
,  " %0 2X" ,  buf
[ j
]); 1673          // add file extension 1674          sprintf ( fnameptr
,  ".eml" );  1677          f 
=  fopen ( filename
,  "w+" ); 1680                  PrintAndLog ( "Can't open file  %s  " ,  filename
); 1685          for  ( i 
=  0 ;  i 
<  numBlocks
;  i
++) { 1686                  if  ( mfEmlGetMem ( buf
,  i
,  1 )) { 1687                          PrintAndLog ( "Cant get block:  %d " ,  i
); 1690                  for  ( j 
=  0 ;  j 
<  16 ;  j
++) 1691                          fprintf ( f
,  " %0 2X" ,  buf
[ j
]);  1696          PrintAndLog ( "Saved  %d  blocks to file:  %s " ,  numBlocks
,  filename
); 1702  int  CmdHF14AMfECFill ( const char  * Cmd
) 1704          uint8_t  keyType 
=  0 ; 1705          uint8_t  numSectors 
=  16 ; 1707          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1708                  PrintAndLog ( "Usage:  hf mf ecfill <key A/B> [card memory]" ); 1709                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1711                  PrintAndLog ( "samples:  hf mf ecfill A" ); 1712                  PrintAndLog ( "          hf mf ecfill A 4" ); 1713                  PrintAndLog ( "Read card and transfer its data to emulator memory." ); 1714                  PrintAndLog ( "Keys must be laid in the emulator memory.  \n " ); 1718          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1719          if  ( ctmp 
!=  'a'  &&  ctmp 
!=  'A'  &&  ctmp 
!=  'b'  &&  ctmp 
!=  'B' ) { 1720                  PrintAndLog ( "Key type must be A or B" ); 1723          if  ( ctmp 
!=  'A'  &&  ctmp 
!=  'a' )  keyType 
=  1 ; 1725          ctmp 
=  param_getchar ( Cmd
,  1 ); 1727                  case  '0'  :  numSectors 
=  5 ;  break ; 1729                  case  '\0' :  numSectors 
=  16 ;  break ; 1730                  case  '2'  :  numSectors 
=  32 ;  break ; 1731                  case  '4'  :  numSectors 
=  40 ;  break ; 1732                  default :    numSectors 
=  16 ; 1735          printf ( "--params: numSectors:  %d , keyType: %d " ,  numSectors
,  keyType
); 1736          UsbCommand c 
= { CMD_MIFARE_EML_CARDLOAD
, { numSectors
,  keyType
,  0 }}; 1742  int  CmdHF14AMfEKeyPrn ( const char  * Cmd
) 1747          uint64_t  keyA
,  keyB
; 1749          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 1750                  PrintAndLog ( "It prints the keys loaded in the emulator memory" ); 1751                  PrintAndLog ( "Usage:  hf mf ekeyprn [card memory]" ); 1752                  PrintAndLog ( "  [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K" ); 1754                  PrintAndLog ( " sample: hf mf ekeyprn 1" ); 1758          char  cmdp 
=  param_getchar ( Cmd
,  0 ); 1761                  case  '0'  :  numSectors 
=  5 ;  break ; 1763                  case  '\0' :  numSectors 
=  16 ;  break ; 1764                  case  '2'  :  numSectors 
=  32 ;  break ; 1765                  case  '4'  :  numSectors 
=  40 ;  break ; 1766                  default :    numSectors 
=  16 ; 1769          PrintAndLog ( "|---|----------------|----------------|" ); 1770          PrintAndLog ( "|sec|key A           |key B           |" ); 1771          PrintAndLog ( "|---|----------------|----------------|" ); 1772          for  ( i 
=  0 ;  i 
<  numSectors
;  i
++) { 1773                  if  ( mfEmlGetMem ( data
,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ,  1 )) { 1774                          PrintAndLog ( "error get block  %d " ,  FirstBlockOfSector ( i
) +  NumBlocksPerSector ( i
) -  1 ); 1777                  keyA 
=  bytes_to_num ( data
,  6 ); 1778                  keyB 
=  bytes_to_num ( data 
+  10 ,  6 ); 1779                  PrintAndLog ( "| %0 3d|   %0 12"  PRIx64 
"  |   %0 12"  PRIx64 
"  |" ,  i
,  keyA
,  keyB
); 1781          PrintAndLog ( "|---|----------------|----------------|" ); 1787  int  CmdHF14AMfCSetUID ( const char  * Cmd
) 1789          uint8_t  wipeCard 
=  0 ; 1790          uint8_t  uid
[ 8 ] = { 0x00 }; 1791          uint8_t  oldUid
[ 8 ] = { 0x00 }; 1792          uint8_t  atqa
[ 2 ] = { 0x00 }; 1793          uint8_t  sak
[ 1 ] = { 0x00 }; 1794          uint8_t  atqaPresent 
=  1 ; 1799          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  argi
) ==  'h' ) { 1800                  PrintAndLog ( "Usage:  hf mf csetuid <UID 8 hex symbols> [ATQA 4 hex symbols SAK 2 hex symbols] [w]" ); 1801                  PrintAndLog ( "sample:  hf mf csetuid 01020304" ); 1802                  PrintAndLog ( "sample:  hf mf csetuid 01020304 0004 08 w" ); 1803                  PrintAndLog ( "Set UID, ATQA, and SAK for magic Chinese card (only works with such cards)" ); 1804                  PrintAndLog ( "If you also want to wipe the card then add 'w' at the end of the command line." ); 1808          if  ( param_getchar ( Cmd
,  argi
) &&  param_gethex ( Cmd
,  argi
,  uid
,  8 )) { 1809                  PrintAndLog ( "UID must include 8 HEX symbols" ); 1814          ctmp 
=  param_getchar ( Cmd
,  argi
); 1815          if  ( ctmp 
==  'w'  ||  ctmp 
==  'W' ) { 1821                  if  ( param_getchar ( Cmd
,  argi
)) { 1822                          if  ( param_gethex ( Cmd
,  argi
,  atqa
,  4 )) { 1823                                  PrintAndLog ( "ATQA must include 4 HEX symbols" ); 1827                          if  (! param_getchar ( Cmd
,  argi
) ||  param_gethex ( Cmd
,  argi
,  sak
,  2 )) { 1828                                  PrintAndLog ( "SAK must include 2 HEX symbols" ); 1837                  ctmp 
=  param_getchar ( Cmd
,  argi
); 1838                  if  ( ctmp 
==  'w'  ||  ctmp 
==  'W' ) { 1843          PrintAndLog ( "--wipe card: %s   uid: %s " , ( wipeCard
)? "YES" : "NO" ,  sprint_hex ( uid
,  4 )); 1845          res 
=  mfCSetUID ( uid
, ( atqaPresent
)? atqa
: NULL
, ( atqaPresent
)? sak
: NULL
,  oldUid
,  wipeCard
); 1847                          PrintAndLog ( "Can't set UID. error= %d " ,  res
); 1851          PrintAndLog ( "old UID: %s " ,  sprint_hex ( oldUid
,  4 )); 1852          PrintAndLog ( "new UID: %s " ,  sprint_hex ( uid
,  4 )); 1856  int  CmdHF14AMfCSetBlk ( const char  * Cmd
) 1858          uint8_t  memBlock
[ 16 ] = { 0x00 }; 1859          uint8_t  blockNo 
=  0 ; 1860          bool  wipeCard 
=  false ; 1863          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1864                  PrintAndLog ( "Usage:  hf mf csetblk <block number> <block data (32 hex symbols)> [w]" ); 1865                  PrintAndLog ( "sample:  hf mf csetblk 1 01020304050607080910111213141516" ); 1866                  PrintAndLog ( "Set block data for magic Chinese card (only works with such cards)" ); 1867                  PrintAndLog ( "If you also want wipe the card then add 'w' at the end of the command line" ); 1871          blockNo 
=  param_get8 ( Cmd
,  0 ); 1873          if  ( param_gethex ( Cmd
,  1 ,  memBlock
,  32 )) { 1874                  PrintAndLog ( "block data must include 32 HEX symbols" ); 1878          char  ctmp 
=  param_getchar ( Cmd
,  2 ); 1879          wipeCard 
= ( ctmp 
==  'w'  ||  ctmp 
==  'W' ); 1880          PrintAndLog ( "--block number: %2 d data: %s " ,  blockNo
,  sprint_hex ( memBlock
,  16 )); 1882          res 
=  mfCSetBlock ( blockNo
,  memBlock
,  NULL
,  wipeCard
,  CSETBLOCK_SINGLE_OPER
); 1884                  PrintAndLog ( "Can't write block. error= %d " ,  res
); 1891  int  CmdHF14AMfCLoad ( const char  * Cmd
) 1894          char  filename
[ FILE_PATH_SIZE
] = { 0x00 }; 1895          char  *  fnameptr 
=  filename
; 1896          char  buf
[ 64 ] = { 0x00 }; 1897          uint8_t  buf8
[ 64 ] = { 0x00 }; 1898          uint8_t  fillFromEmulator 
=  0 ; 1899          int  i
,  len
,  blockNum
,  flags
= 0 ; 1901          if  ( param_getchar ( Cmd
,  0 ) ==  'h'  ||  param_getchar ( Cmd
,  0 )==  0x00 ) { 1902                  PrintAndLog ( "It loads magic Chinese card from the file `filename.eml`" ); 1903                  PrintAndLog ( "or from emulator memory (option `e`)" ); 1904                  PrintAndLog ( "Usage:  hf mf cload <file name w/o `.eml`>" ); 1905                  PrintAndLog ( "   or:  hf mf cload e " ); 1906                  PrintAndLog ( " sample: hf mf cload filename" ); 1910          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 1911          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ; 1913          if  ( fillFromEmulator
) { 1914                  for  ( blockNum 
=  0 ;  blockNum 
<  16  *  4 ;  blockNum 
+=  1 ) { 1915                          if  ( mfEmlGetMem ( buf8
,  blockNum
,  1 )) { 1916                                  PrintAndLog ( "Cant get block:  %d " ,  blockNum
); 1919                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence 1920                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write 1921                          if  ( blockNum 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;              // Done. Magic Halt and switch off field. 1923                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) { 1924                                  PrintAndLog ( "Cant set magic card block:  %d " ,  blockNum
); 1931                  if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 1933                  memcpy ( filename
,  Cmd
,  len
); 1936                  sprintf ( fnameptr
,  ".eml" );  1939                  f 
=  fopen ( filename
,  "r" ); 1941                          PrintAndLog ( "File not found or locked." ); 1948                          memset ( buf
,  0 ,  sizeof ( buf
)); 1950                          if  ( fgets ( buf
,  sizeof ( buf
),  f
) ==  NULL
) { 1952                                  PrintAndLog ( "File reading error." ); 1956                          if  ( strlen ( buf
) <  32 ) { 1957                                  if ( strlen ( buf
) &&  feof ( f
)) 1959                                  PrintAndLog ( "File content error. Block data must include 32 HEX symbols" ); 1963                          for  ( i 
=  0 ;  i 
<  32 ;  i 
+=  2 ) 1964                                  sscanf (& buf
[ i
],  " %0 2x" , ( unsigned int  *)& buf8
[ i 
/  2 ]); 1966                          if  ( blockNum 
==  0 )  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
;                                // switch on field and send magic sequence 1967                          if  ( blockNum 
==  1 )  flags 
=  0 ;                                                                                                    // just write 1968                          if  ( blockNum 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
;              // Done. Switch off field. 1970                          if  ( mfCSetBlock ( blockNum
,  buf8
,  NULL
,  0 ,  flags
)) { 1971                                  PrintAndLog ( "Can't set magic card block:  %d " ,  blockNum
); 1977                          if  ( blockNum 
>=  16  *  4 )  break ;   // magic card type - mifare 1K 1981                  if  ( blockNum 
!=  16  *  4  &&  blockNum 
!=  32  *  4  +  8  *  16 ){ 1982                          PrintAndLog ( "File content error. There must be 64 blocks" ); 1985                  PrintAndLog ( "Loaded from file:  %s " ,  filename
); 1991  int  CmdHF14AMfCGetBlk ( const char  * Cmd
) { 1992          uint8_t  memBlock
[ 16 ]; 1993          uint8_t  blockNo 
=  0 ; 1995          memset ( memBlock
,  0x00 ,  sizeof ( memBlock
)); 1997          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 1998                  PrintAndLog ( "Usage:  hf mf cgetblk <block number>" ); 1999                  PrintAndLog ( "sample:  hf mf cgetblk 1" ); 2000                  PrintAndLog ( "Get block data from magic Chinese card (only works with such cards) \n " ); 2004          blockNo 
=  param_get8 ( Cmd
,  0 ); 2006          PrintAndLog ( "--block number: %2 d " ,  blockNo
); 2008          res 
=  mfCGetBlock ( blockNo
,  memBlock
,  CSETBLOCK_SINGLE_OPER
); 2010                          PrintAndLog ( "Can't read block. error= %d " ,  res
); 2014          PrintAndLog ( "block data: %s " ,  sprint_hex ( memBlock
,  16 )); 2019  int  CmdHF14AMfCGetSc ( const char  * Cmd
) { 2020          uint8_t  memBlock
[ 16 ] = { 0x00 }; 2021          uint8_t  sectorNo 
=  0 ; 2024          if  ( strlen ( Cmd
) <  1  ||  param_getchar ( Cmd
,  0 ) ==  'h' ) { 2025                  PrintAndLog ( "Usage:  hf mf cgetsc <sector number>" ); 2026                  PrintAndLog ( "sample:  hf mf cgetsc 0" ); 2027                  PrintAndLog ( "Get sector data from magic Chinese card (only works with such cards) \n " ); 2031          sectorNo 
=  param_get8 ( Cmd
,  0 ); 2032          if  ( sectorNo 
>  15 ) { 2033                  PrintAndLog ( "Sector number must be in [0..15] as in MIFARE classic." ); 2037          PrintAndLog ( "--sector number: %d  " ,  sectorNo
); 2039          flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 2040          for  ( i 
=  0 ;  i 
<  4 ;  i
++) { 2041                  if  ( i 
==  1 )  flags 
=  0 ; 2042                  if  ( i 
==  3 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 2044                  res 
=  mfCGetBlock ( sectorNo 
*  4  +  i
,  memBlock
,  flags
); 2046                          PrintAndLog ( "Can't read block.  %d  error= %d " ,  sectorNo 
*  4  +  i
,  res
); 2050                  PrintAndLog ( "block  %3 d data: %s " ,  sectorNo 
*  4  +  i
,  sprint_hex ( memBlock
,  16 )); 2056  int  CmdHF14AMfCSave ( const char  * Cmd
) { 2059          char  filename
[ FILE_PATH_SIZE
] = { 0x00 }; 2060          char  *  fnameptr 
=  filename
; 2061          uint8_t  fillFromEmulator 
=  0 ; 2062          uint8_t  buf
[ 64 ] = { 0x00 }; 2063          int  i
,  j
,  len
,  flags
; 2065          // memset(filename, 0, sizeof(filename)); 2066          // memset(buf, 0, sizeof(buf)); 2068          if  ( param_getchar ( Cmd
,  0 ) ==  'h' ) { 2069                  PrintAndLog ( "It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`" ); 2070                  PrintAndLog ( "or into emulator memory (option `e`)" ); 2071                  PrintAndLog ( "Usage:  hf mf esave [file name w/o `.eml`][e]" ); 2072                  PrintAndLog ( " sample: hf mf esave " ); 2073                  PrintAndLog ( "         hf mf esave filename" ); 2074                  PrintAndLog ( "         hf mf esave e  \n " ); 2078          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 2079          if  ( ctmp 
==  'e'  ||  ctmp 
==  'E' )  fillFromEmulator 
=  1 ; 2081          if  ( fillFromEmulator
) { 2082                  // put into emulator 2083                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 2084                  for  ( i 
=  0 ;  i 
<  16  *  4 ;  i
++) { 2085                          if  ( i 
==  1 )  flags 
=  0 ; 2086                          if  ( i 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 2088                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) { 2089                                  PrintAndLog ( "Cant get block:  %d " ,  i
); 2093                          if  ( mfEmlSetMem ( buf
,  i
,  1 )) { 2094                                  PrintAndLog ( "Cant set emul block:  %d " ,  i
); 2101                  if  ( len 
>  FILE_PATH_SIZE 
-  5 )  len 
=  FILE_PATH_SIZE 
-  5 ; 2105                          if  ( mfCGetBlock ( 0 ,  buf
,  CSETBLOCK_SINGLE_OPER
)) { 2106                                  PrintAndLog ( "Cant get block:  %d " ,  0 ); 2107                                  len 
=  sprintf ( fnameptr
,  "dump" ); 2111                                  for  ( j 
=  0 ;  j 
<  7 ;  j
++,  fnameptr 
+=  2 ) 2112                                          sprintf ( fnameptr
,  " %0 2x" ,  buf
[ j
]);  2115                          memcpy ( filename
,  Cmd
,  len
); 2119                  sprintf ( fnameptr
,  ".eml" );  2122                  f 
=  fopen ( filename
,  "w+" ); 2125                          PrintAndLog ( "File not found or locked." ); 2130                  flags 
=  CSETBLOCK_INIT_FIELD 
+  CSETBLOCK_WUPC
; 2131                  for  ( i 
=  0 ;  i 
<  16  *  4 ;  i
++) { 2132                          if  ( i 
==  1 )  flags 
=  0 ; 2133                          if  ( i 
==  16  *  4  -  1 )  flags 
=  CSETBLOCK_HALT 
+  CSETBLOCK_RESET_FIELD
; 2135                          if  ( mfCGetBlock ( i
,  buf
,  flags
)) { 2136                                  PrintAndLog ( "Cant get block:  %d " ,  i
); 2139                          for  ( j 
=  0 ;  j 
<  16 ;  j
++) 2140                                  fprintf ( f
,  " %0 2x" ,  buf
[ j
]);  2145                  PrintAndLog ( "Saved to file:  %s " ,  filename
); 2152  int  CmdHF14AMfSniff ( const char  * Cmd
){ 2154          bool  wantLogToFile 
=  0 ; 2155          bool  wantDecrypt 
=  0 ; 2156          //bool wantSaveToEml = 0; TODO 2157          bool  wantSaveToEmlFile 
=  0 ; 2167          uint8_t  atqa
[ 2 ] = { 0x00 }; 2170          uint8_t  * buf 
=  NULL
; 2171          uint16_t  bufsize 
=  0 ; 2172          uint8_t  * bufPtr 
=  NULL
; 2174          char  ctmp 
=  param_getchar ( Cmd
,  0 ); 2175          if  (  ctmp 
==  'h'  ||  ctmp 
==  'H'  ) { 2176                  PrintAndLog ( "It continuously gets data from the field and saves it to: log, emulator, emulator file." ); 2177                  PrintAndLog ( "You can specify:" ); 2178                  PrintAndLog ( "    l - save encrypted sequence to logfile `uid.log`" ); 2179                  PrintAndLog ( "    d - decrypt sequence and put it to log file `uid.log`" ); 2180                  PrintAndLog ( " n/a   e - decrypt sequence, collect read and write commands and save the result of the sequence to emulator memory" ); 2181                  PrintAndLog ( "    f - decrypt sequence, collect read and write commands and save the result of the sequence to emulator dump file `uid.eml`" ); 2182                  PrintAndLog ( "Usage:  hf mf sniff [l][d][e][f]" ); 2183                  PrintAndLog ( "  sample: hf mf sniff l d e" ); 2187          for  ( int  i 
=  0 ;  i 
<  4 ;  i
++) { 2188                  ctmp 
=  param_getchar ( Cmd
,  i
); 2189                  if  ( ctmp 
==  'l'  ||  ctmp 
==  'L' )  wantLogToFile 
=  true ; 2190                  if  ( ctmp 
==  'd'  ||  ctmp 
==  'D' )  wantDecrypt 
=  true ; 2191                  //if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO 2192                  if  ( ctmp 
==  'f'  ||  ctmp 
==  'F' )  wantSaveToEmlFile 
=  true ; 2195          printf ( "------------------------------------------------------------------------- \n " ); 2196          printf ( "Executing command.  \n " ); 2197          printf ( "Press the key on the proxmark3 device to abort both proxmark3 and client. \n " ); 2198          printf ( "Press the key on pc keyboard to abort the client. \n " ); 2199          printf ( "------------------------------------------------------------------------- \n " ); 2201          UsbCommand c 
= { CMD_MIFARE_SNIFFER
, { 0 ,  0 ,  0 }}; 2202          clearCommandBuffer (); 2211                          printf ( " \n aborted via keyboard! \n " ); 2216                  if  ( WaitForResponseTimeout ( CMD_ACK
,& resp
, 2000 )) { 2217                          res 
=  resp
. arg
[ 0 ] &  0xff ; 2218                          uint16_t  traceLen 
=  resp
. arg
[ 1 ]; 2221                          if  ( res 
==  0 ) {                                                          // we are done 2226                          if  ( res 
==  1 ) {                                                          // there is (more) data to be transferred 2227                                  if  ( pckNum 
==  0 ) {                                               // first packet, (re)allocate necessary buffer 2228                                          if  ( traceLen 
>  bufsize 
||  buf 
==  NULL
) { 2230                                                  if  ( buf 
==  NULL
) {                               // not yet allocated 2231                                                          p 
=  malloc ( traceLen
); 2232                                                  }  else  {                                                 // need more memory 2233                                                          p 
=  realloc ( buf
,  traceLen
); 2236                                                          PrintAndLog ( "Cannot allocate memory for trace" ); 2244                                          memset ( buf
,  0x00 ,  traceLen
); 2246                                  memcpy ( bufPtr
,  resp
. d
. asBytes
,  len
); 2251                          if  ( res 
==  2 ) {                                                          // received all data, start displaying 2252                                  blockLen 
=  bufPtr 
-  buf
; 2255                                  PrintAndLog ( "received trace len:  %d  packages:  %d " ,  blockLen
,  pckNum
); 2256                                  while  ( bufPtr 
-  buf 
<  blockLen
) { 2257                                          bufPtr 
+=  6 ;                                             // skip (void) timing information 2258                                          len 
= *(( uint16_t  *) bufPtr
); 2266                                          if  (( len 
==  14 ) && ( bufPtr
[ 0 ] ==  0xff ) && ( bufPtr
[ 1 ] ==  0xff ) && ( bufPtr
[ 12 ] ==  0xff ) && ( bufPtr
[ 13 ] ==  0xff )) { 2267                                                  memcpy ( uid
,  bufPtr 
+  2 ,  7 ); 2268                                                  memcpy ( atqa
,  bufPtr 
+  2  +  7 ,  2 ); 2269                                                  uid_len 
= ( atqa
[ 0 ] &  0xC0 ) ==  0x40  ?  7  :  4 ; 2271                                                  PrintAndLog ( "tag select uid: %s  atqa:0x %0 2x %0 2x sak:0x %0 2x" ,  2272                                                          sprint_hex ( uid 
+ ( 7  -  uid_len
),  uid_len
), 2276                                                  if  ( wantLogToFile 
||  wantDecrypt
) { 2277                                                          FillFileNameByUID ( logHexFileName
,  uid 
+ ( 7  -  uid_len
),  ".log" ,  uid_len
); 2278                                                          AddLogCurrentDT ( logHexFileName
); 2281                                                          mfTraceInit ( uid
,  atqa
,  sak
,  wantSaveToEmlFile
); 2283                                                  PrintAndLog ( " %s ( %d ): %s " ,  isTag 
?  "TAG" : "RDR" ,  num
,  sprint_hex ( bufPtr
,  len
)); 2285                                                          AddLogHex ( logHexFileName
,  isTag 
?  "TAG: " : "RDR: " ,  bufPtr
,  len
); 2287                                                          mfTraceDecode ( bufPtr
,  len
,  wantSaveToEmlFile
); 2291                                          bufPtr 
+= (( len
- 1 )/ 8 + 1 );         // ignore parity 2302  //needs nt, ar, at, Data to decrypt 2303  int  CmdDecryptTraceCmds ( const char  * Cmd
){ 2306          param_gethex_ex ( Cmd
, 3 , data
,& len
); 2307          return  tryDecryptWord ( param_get32ex ( Cmd
, 0 , 0 , 16 ), param_get32ex ( Cmd
, 1 , 0 , 16 ), param_get32ex ( Cmd
, 2 , 0 , 16 ), data
, len
/ 2 ); 2310  static  command_t CommandTable
[] = 2312    { "help" ,              CmdHelp
,                  1 ,  "This help" }, 2313    { "dbg" ,               CmdHF14AMfDbg
,            0 ,  "Set default debug mode" }, 2314    { "rdbl" ,              CmdHF14AMfRdBl
,           0 ,  "Read MIFARE classic block" }, 2315    { "rdsc" ,              CmdHF14AMfRdSc
,           0 ,  "Read MIFARE classic sector" }, 2316    { "dump" ,              CmdHF14AMfDump
,           0 ,  "Dump MIFARE classic tag to binary file" }, 2317    { "restore" ,           CmdHF14AMfRestore
,        0 ,  "Restore MIFARE classic binary file to BLANK tag" }, 2318    { "wrbl" ,              CmdHF14AMfWrBl
,           0 ,  "Write MIFARE classic block" }, 2319    { "chk" ,               CmdHF14AMfChk
,            0 ,  "Test block keys" }, 2320    { "mifare" ,            CmdHF14AMifare
,           0 ,  "Read parity error messages." }, 2321    { "hardnested" ,        CmdHF14AMfNestedHard
,     0 ,  "Nested attack for hardened Mifare cards" }, 2322    { "nested" ,            CmdHF14AMfNested
,         0 ,  "Test nested authentication" }, 2323    { "sniff" ,             CmdHF14AMfSniff
,          0 ,  "Sniff card-reader communication" }, 2324    { "sim" ,               CmdHF14AMf1kSim
,          0 ,  "Simulate MIFARE card" }, 2325    { "eclr" ,              CmdHF14AMfEClear
,         0 ,  "Clear simulator memory block" }, 2326    { "eget" ,              CmdHF14AMfEGet
,           0 ,  "Get simulator memory block" }, 2327    { "eset" ,              CmdHF14AMfESet
,           0 ,  "Set simulator memory block" }, 2328    { "eload" ,             CmdHF14AMfELoad
,          0 ,  "Load from file emul dump" }, 2329    { "esave" ,             CmdHF14AMfESave
,          0 ,  "Save to file emul dump" }, 2330    { "ecfill" ,            CmdHF14AMfECFill
,         0 ,  "Fill simulator memory with help of keys from simulator" }, 2331    { "ekeyprn" ,           CmdHF14AMfEKeyPrn
,        0 ,  "Print keys from simulator memory" }, 2332    { "csetuid" ,           CmdHF14AMfCSetUID
,        0 ,  "Set UID for magic Chinese card" }, 2333    { "csetblk" ,           CmdHF14AMfCSetBlk
,        0 ,  "Write block - Magic Chinese card" }, 2334    { "cgetblk" ,           CmdHF14AMfCGetBlk
,        0 ,  "Read block - Magic Chinese card" }, 2335    { "cgetsc" ,            CmdHF14AMfCGetSc
,         0 ,  "Read sector - Magic Chinese card" }, 2336    { "cload" ,             CmdHF14AMfCLoad
,          0 ,  "Load dump into magic Chinese card" }, 2337    { "csave" ,             CmdHF14AMfCSave
,          0 ,  "Save dump from magic Chinese card into file or emulator" }, 2338    { "decrypt" ,           CmdDecryptTraceCmds
,      1 ,  "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace" }, 2339    { NULL
,                NULL
,                     0 ,  NULL
} 2342  int  CmdHFMF ( const char  * Cmd
) 2345          WaitForResponseTimeout ( CMD_ACK
, NULL
, 100 ); 2347    CmdsParse ( CommandTable
,  Cmd
); 2351  int  CmdHelp ( const char  * Cmd
) 2353    CmdsHelp ( CommandTable
);