00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #endif // HAVE_CONFIG_H
00028
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <stdint.h>
00032 #include <stddef.h>
00033 #include <stdbool.h>
00034
00035 #include <string.h>
00036 #include <ctype.h>
00037
00038 #include <nfc/nfc.h>
00039
00040 #include "mifareultag.h"
00041 #include "bitutils.h"
00042
00043 static nfc_device_t* pnd;
00044 static nfc_target_info_t nti;
00045 static mifare_param mp;
00046 static mifareul_tag mtDump;
00047 static uint32_t uiBlocks = 0xF;
00048
00049 void print_success_or_failure(bool bFailure, uint32_t* uiBlockCounter)
00050 {
00051 printf("%c",(bFailure)?'x':'.');
00052 if (uiBlockCounter)
00053 *uiBlockCounter += (bFailure)?0:1;
00054 }
00055
00056 bool read_card()
00057 {
00058 uint32_t page;
00059 bool bFailure = false;
00060 uint32_t uiReadBlocks = 0;
00061
00062 printf("Reading out %d blocks |",uiBlocks+1);
00063
00064 for (page = 0; page <= uiBlocks; page += 4)
00065 {
00066
00067 if (page != 0)
00068 {
00069 print_success_or_failure(bFailure, &uiReadBlocks);
00070 print_success_or_failure(bFailure, &uiReadBlocks);
00071 print_success_or_failure(bFailure, &uiReadBlocks);
00072 print_success_or_failure(bFailure, &uiReadBlocks);
00073 }
00074
00075
00076 if (nfc_initiator_mifare_cmd(pnd,MC_READ,page,&mp))
00077 {
00078 memcpy(mtDump.amb[page / 4].mbd.abtData, mp.mpd.abtData, 16);
00079 } else {
00080 bFailure = true;
00081 break;
00082 }
00083 }
00084
00085 print_success_or_failure(bFailure, &uiReadBlocks);
00086 printf("|\n");
00087 printf("Done, %d of %d blocks read.\n", uiReadBlocks, uiBlocks+1);
00088 fflush(stdout);
00089
00090 return (!bFailure);
00091 }
00092
00093 bool write_card()
00094 {
00095 uint32_t uiBlock = 0;
00096 int page;
00097 bool bFailure = false;
00098 uint32_t uiWriteBlocks = 0;
00099
00100 for (page = 0x4; page <= 0xF; page++) {
00101
00102 if (bFailure)
00103 {
00104 printf("x");
00105
00106 if (!nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
00107 {
00108 printf("!\nError: tag was removed\n");
00109 return false;
00110 }
00111 bFailure = false;
00112 }
00113 fflush(stdout);
00114
00115
00116 if (!bFailure)
00117 {
00118
00119
00120
00121
00122 uiBlock = page / 4;
00123 memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData + ((page % 4) * 4), 16);
00124 if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, page, &mp)) bFailure = true;
00125 }
00126 }
00127 print_success_or_failure(bFailure, &uiWriteBlocks);
00128 printf("|\n");
00129 printf("Done, %d of %d blocks written.\n", uiWriteBlocks, uiBlocks+1);
00130 fflush(stdout);
00131
00132 return true;
00133 }
00134
00135 int main(int argc, const char* argv[])
00136 {
00137 bool bReadAction;
00138 byte_t* pbtUID;
00139 FILE* pfDump;
00140
00141 if (argc < 3)
00142 {
00143 printf("\n");
00144 printf("%s r|w <dump.mfd>\n", argv[0]);
00145 printf("\n");
00146 printf("r|w - Perform read from or write to card\n");
00147 printf("<dump.mfd> - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
00148 printf("\n");
00149 return 1;
00150 }
00151
00152 printf("\nChecking arguments and settings\n");
00153
00154 bReadAction = tolower((int)((unsigned char)*(argv[1])) == 'r');
00155
00156 if (bReadAction)
00157 {
00158 memset(&mtDump,0x00,sizeof(mtDump));
00159 } else {
00160 pfDump = fopen(argv[2],"rb");
00161
00162 if (pfDump == NULL)
00163 {
00164 printf("Could not open dump file: %s\n",argv[2]);
00165 return 1;
00166 }
00167
00168 if (fread(&mtDump,1,sizeof(mtDump),pfDump) != sizeof(mtDump))
00169 {
00170 printf("Could not read from dump file: %s\n",argv[2]);
00171 fclose(pfDump);
00172 return 1;
00173 }
00174 fclose(pfDump);
00175 }
00176 printf("Succesful opened the dump file\n");
00177
00178
00179 pnd = nfc_connect(NULL);
00180 if (pnd == NULL)
00181 {
00182 printf("Error connecting NFC reader\n");
00183 return 1;
00184 }
00185
00186 nfc_initiator_init(pnd);
00187
00188
00189 nfc_configure(pnd,NDO_ACTIVATE_FIELD,false);
00190
00191
00192 nfc_configure(pnd,NDO_INFINITE_SELECT,false);
00193 nfc_configure(pnd,NDO_HANDLE_CRC,true);
00194 nfc_configure(pnd,NDO_HANDLE_PARITY,true);
00195
00196
00197 nfc_configure(pnd,NDO_ACTIVATE_FIELD,true);
00198
00199 printf("Connected to NFC reader: %s\n",pnd->acName);
00200
00201
00202 if (!nfc_initiator_select_tag(pnd,NM_ISO14443A_106,NULL,0,&nti))
00203 {
00204 printf("Error: no tag was found\n");
00205 nfc_disconnect(pnd);
00206 return 1;
00207 }
00208
00209
00210
00211 if (nti.nai.abtAtqa[1] != 0x44){
00212 printf("Error: tag is not a MIFARE Ultralight card\n");
00213 nfc_disconnect(pnd);
00214 return 1;
00215 }
00216
00217
00218
00219 pbtUID = nti.nai.abtUid;
00220 printf("Found MIFARE Ultralight card with uid: %08x\n", swap_endian32(pbtUID));
00221
00222 if (bReadAction)
00223 {
00224 if (read_card())
00225 {
00226 printf("Writing data to file: %s ... ",argv[2]);
00227 fflush(stdout);
00228 pfDump = fopen(argv[2],"wb");
00229 if (pfDump == NULL)
00230 {
00231 printf("Could not open file: %s\n",argv[2]);
00232 return 1;
00233 }
00234 if (fwrite(&mtDump,1,sizeof(mtDump),pfDump) != sizeof(mtDump))
00235 {
00236 printf("Could not write to file: %s\n",argv[2]);
00237 return 1;
00238 }
00239 fclose(pfDump);
00240 printf("Done.\n");
00241 }
00242 } else {
00243 write_card();
00244 }
00245
00246 nfc_disconnect(pnd);
00247
00248 return 0;
00249 }