int main(int argc, const char *argv[]) { int iAction = 0; uint8_t iUID[MAX_UID_LEN] = { 0x0 }; size_t szUID = 0; bool bOTP = false; bool bLock = false; bool bUID = false; FILE *pfDump; if (argc < 2) { print_usage(argv); exit(EXIT_FAILURE); } DBG("\nChecking arguments and settings\n"); // Get commandline options for (int arg = 1; arg < argc; arg++) { if (0 == strcmp(argv[arg], "r")) { iAction = 1; } else if (0 == strcmp(argv[arg], "w")) { iAction = 2; } else if (0 == strcmp(argv[arg], "--with-uid")) { if (argc < 5) { ERR("Please supply a UID of 4, 7 or 10 bytes long. Ex: a1:b2:c3:d4"); exit(EXIT_FAILURE); } szUID = str_to_uid(argv[4], iUID); } else if (0 == strcmp(argv[arg], "--full")) { bOTP = true; bLock = true; bUID = true; } else if (0 == strcmp(argv[arg], "--otp")) { bOTP = true; } else if (0 == strcmp(argv[arg], "--lock")) { bLock = true; } else if (0 == strcmp(argv[arg], "--uid")) { bUID = true; } else if (0 == strcmp(argv[arg], "--check-magic")) { iAction = 3; } else { //Skip validation of the filename if ((arg != 2) && (arg != 4)) { ERR("%s is not supported option.", argv[arg]); print_usage(argv); exit(EXIT_FAILURE); } } } if (iAction == 1) { memset(&mtDump, 0x00, sizeof(mtDump)); } else if (iAction == 2) { pfDump = fopen(argv[2], "rb"); if (pfDump == NULL) { ERR("Could not open dump file: %s\n", argv[2]); exit(EXIT_FAILURE); } if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { ERR("Could not read from dump file: %s\n", argv[2]); fclose(pfDump); exit(EXIT_FAILURE); } fclose(pfDump); DBG("Successfully opened the dump file\n"); } else if (iAction == 3) { DBG("Switching to Check Magic Mode\n"); } else { ERR("Unable to determine operating mode"); exit(EXIT_FAILURE); } nfc_context *context; nfc_init(&context); if (context == NULL) { ERR("Unable to init libnfc (malloc)"); exit(EXIT_FAILURE); } // Try to open the NFC device pnd = nfc_open(context, NULL); if (pnd == NULL) { ERR("Error opening NFC device"); nfc_exit(context); exit(EXIT_FAILURE); } printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); if (list_passive_targets(pnd)) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Let the device only try once to find a tag if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Try to find a MIFARE Ultralight tag if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) { ERR("no tag was found\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Test if we are dealing with a MIFARE compatible tag if (nt.nti.nai.abtAtqa[1] != 0x44) { ERR("tag is not a MIFARE Ultralight card\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Get the info from the current tag printf("Using MIFARE Ultralight card with UID: "); size_t szPos; for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) { printf("%02x", nt.nti.nai.abtUid[szPos]); } printf("\n"); if (iAction == 1) { if (read_card()) { printf("Writing data to file: %s ... ", argv[2]); fflush(stdout); pfDump = fopen(argv[2], "wb"); if (pfDump == NULL) { printf("Could not open file: %s\n", argv[2]); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { printf("Could not write to file: %s\n", argv[2]); fclose(pfDump); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } fclose(pfDump); printf("Done.\n"); } } else if (iAction == 2) { write_card(bOTP, bLock, bUID); } else if (iAction == 3) { if (!check_magic()) { printf("Card is not magic\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } else { printf("Card is magic\n"); } } nfc_close(pnd); nfc_exit(context); exit(EXIT_SUCCESS); }
int main(int argc, const char *argv[]) { int iAction = 0; uint8_t iDumpSize = sizeof(mifareul_tag); uint8_t iUID[MAX_UID_LEN] = { 0x0 }; size_t szUID = 0; bool bOTP = false; bool bLock = false; bool bUID = false; bool bPWD = false; bool bPart = false; bool bFilename = false; FILE *pfDump; if (argc < 3) { print_usage(argv); exit(EXIT_FAILURE); } DBG("\nChecking arguments and settings\n"); // Get commandline options for (int arg = 1; arg < argc; arg++) { if (0 == strcmp(argv[arg], "r")) { iAction = 1; } else if (0 == strcmp(argv[arg], "w")) { iAction = 2; } else if (0 == strcmp(argv[arg], "--with-uid")) { if (arg + 1 == argc) { ERR("Please supply a UID of 4, 7 or 10 bytes long. Ex: a1:b2:c3:d4"); exit(EXIT_FAILURE); } szUID = str_to_uid(argv[++arg], iUID); } else if (0 == strcmp(argv[arg], "--full")) { bOTP = true; bLock = true; bUID = true; } else if (0 == strcmp(argv[arg], "--otp")) { bOTP = true; } else if (0 == strcmp(argv[arg], "--lock")) { bLock = true; } else if (0 == strcmp(argv[arg], "--uid")) { bUID = true; } else if (0 == strcmp(argv[arg], "--check-magic")) { iAction = 3; } else if (0 == strcmp(argv[arg], "--partial")) { bPart = true; } else if (0 == strcmp(argv[arg], "--pw")) { bPWD = true; if (arg + 1 == argc || strlen(argv[++arg]) != 8 || ! ev1_load_pwd(iPWD, argv[arg])) { ERR("Please supply a PASSWORD of 8 HEX digits"); exit(EXIT_FAILURE); } } else { //Skip validation of the filename if (arg != 2) { ERR("%s is not a supported option.", argv[arg]); print_usage(argv); exit(EXIT_FAILURE); } else { bFilename = true; } } } if (! bFilename) { ERR("Please supply a Mifare Dump filename"); exit(EXIT_FAILURE); } nfc_context *context; nfc_init(&context); if (context == NULL) { ERR("Unable to init libnfc (malloc)"); exit(EXIT_FAILURE); } // Try to open the NFC device pnd = nfc_open(context, NULL); if (pnd == NULL) { ERR("Error opening NFC device"); nfc_exit(context); exit(EXIT_FAILURE); } printf("NFC device: %s opened\n", nfc_device_get_name(pnd)); if (list_passive_targets(pnd)) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (nfc_initiator_init(pnd) < 0) { nfc_perror(pnd, "nfc_initiator_init"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Let the device only try once to find a tag if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) { nfc_perror(pnd, "nfc_device_set_property_bool"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Try to find a MIFARE Ultralight tag if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) { ERR("no tag was found\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Test if we are dealing with a MIFARE compatible tag if (nt.nti.nai.abtAtqa[1] != 0x44) { ERR("tag is not a MIFARE Ultralight card\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } // Get the info from the current tag printf("Using MIFARE Ultralight card with UID: "); size_t szPos; for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) { printf("%02x", nt.nti.nai.abtUid[szPos]); } printf("\n"); // test if tag is EV1 if (get_ev1_version()) { if (!bPWD) printf("Tag is EV1 - PASSWORD may be required\n"); printf("EV1 storage size: "); if (abtRx[6] == 0x0b) { printf("48 bytes\n"); uiBlocks = 0x14; iEV1Type = EV1_UL11; iDumpSize = sizeof(mifareul_ev1_mf0ul11_tag); } else if (abtRx[6] == 0x0e) { printf("128 bytes\n"); uiBlocks = 0x29; iEV1Type = EV1_UL21; iDumpSize = sizeof(mifareul_ev1_mf0ul21_tag); } else printf("unknown!\n"); } else { // re-init non EV1 tag if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) { ERR("no tag was found\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } } // EV1 login required if (bPWD) { printf("Authing with PWD: %02x%02x%02x%02x ", iPWD[0], iPWD[1], iPWD[2], iPWD[3]); if (!ev1_pwd_auth(iPWD)) { printf("\n"); ERR("AUTH failed!\n"); exit(EXIT_FAILURE); } else { printf("Success - PACK: %02x%02x\n", abtRx[0], abtRx[1]); memcpy(iPACK, abtRx, 2); } } if (iAction == 1) { memset(&mtDump, 0x00, sizeof(mtDump)); } else if (iAction == 2) { pfDump = fopen(argv[2], "rb"); if (pfDump == NULL) { ERR("Could not open dump file: %s\n", argv[2]); exit(EXIT_FAILURE); } size_t szDump; if (((szDump = fread(&mtDump, 1, sizeof(mtDump), pfDump)) != iDumpSize && !bPart) || szDump <= 0) { ERR("Could not read from dump file or size mismatch: %s\n", argv[2]); fclose(pfDump); exit(EXIT_FAILURE); } if (szDump != iDumpSize) printf("Performing partial write\n"); fclose(pfDump); DBG("Successfully opened the dump file\n"); } else if (iAction == 3) { DBG("Switching to Check Magic Mode\n"); } else { ERR("Unable to determine operating mode"); exit(EXIT_FAILURE); } if (iAction == 1) { bool bRF = read_card(); printf("Writing data to file: %s ... ", argv[2]); fflush(stdout); pfDump = fopen(argv[2], "wb"); if (pfDump == NULL) { printf("Could not open file: %s\n", argv[2]); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } if (fwrite(&mtDump, 1, uiReadPages * 4, pfDump) != uiReadPages * 4) { printf("Could not write to file: %s\n", argv[2]); fclose(pfDump); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } fclose(pfDump); printf("Done.\n"); if (!bRF) printf("Warning! Read failed - partial data written to file!\n"); } else if (iAction == 2) { write_card(bOTP, bLock, bUID); } else if (iAction == 3) { if (!check_magic()) { printf("Card is not magic\n"); nfc_close(pnd); nfc_exit(context); exit(EXIT_FAILURE); } else { printf("Card is magic\n"); } } nfc_close(pnd); nfc_exit(context); exit(EXIT_SUCCESS); }