Пример #1
0
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);
}
Пример #2
0
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);
}