From b44488fbedad1e5b39fda73faec0322909150cc6 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Thu, 30 Apr 2020 20:32:43 +0800 Subject: [PATCH 1/7] Support read/write data in emulator --- module/mifare.cpp | 493 ++++++++++++++++++++++++++-------------------- module/mifare.h | 3 + ui/mainwindow.cpp | 26 ++- ui/mainwindow.h | 9 +- ui/mainwindow.ui | 3 - 5 files changed, 318 insertions(+), 216 deletions(-) diff --git a/module/mifare.cpp b/module/mifare.cpp index 5bd6ddd..642aca4 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -1,6 +1,7 @@ #include "mifare.h" -Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent) : QObject(parent) +Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent) + : QObject(parent) { this->parent = parent; util = addr; @@ -9,27 +10,26 @@ Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent) : QObject(parent keyAList = new QStringList(); keyBList = new QStringList(); dataList = new QStringList(); - data_clearKey(); // fill with blank Qstring + data_clearKey(); // fill with blank Qstring data_clearData(); // fill with blank Qstring dataPattern = new QRegExp("([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"); chkKeyPattern = new QRegExp("\\|\\d{3}\\|.+\\|.+\\|"); nestedKeyPattern = new QRegExp("\\|\\d{3}\\|.+\\|.+\\|.+\\|.+\\|"); } - - QString Mifare::info(bool isRequiringOutput) { - if(isRequiringOutput) + if (isRequiringOutput) { QString result = util->execCMDWithOutput("hf 14a info", 500); - qDebug() << result << result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0); + qDebug() << result + << result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0); result.replace("UID :", "|"); result.replace("ATQA :", "|"); result.replace("SAK :", "|"); result.replace("TYPE :", "|"); QStringList lis = result.split("|"); - if(lis.length() > 4) + if (lis.length() > 4) { qDebug() << lis[1] + lis[2] + lis[3]; return lis[1] + lis[2] + lis[3]; @@ -47,22 +47,25 @@ QString Mifare::info(bool isRequiringOutput) void Mifare::chk() { - QString result = util->execCMDWithOutput("hf mf chk *" + QString::number(cardType.type) + " ?", 1000 + cardType.type * 1000); + QString result = util->execCMDWithOutput( + "hf mf chk *" + QString::number(cardType.type) + " ?", + 1000 + cardType.type * 1000); qDebug() << result; int offset = 0; QString tmp, tmp2; - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { - offset = result.indexOf(*chkKeyPattern, offset); + offset = chkKeyPattern->indexIn(result, offset); +// offset = result.indexOf(*chkKeyPattern, offset); tmp = result.mid(offset, 39).toUpper(); offset += 39; qDebug() << tmp << offset; tmp2 = tmp.mid(7, 12).trimmed(); - if(tmp2 != "?") + if (tmp2 != "?") keyAList->replace(i, tmp2); tmp2 = tmp.mid(24, 12).trimmed(); - if(tmp2 != "?") + if (tmp2 != "?") keyBList->replace(i, tmp2); } data_syncWithKeyWidget(); @@ -70,18 +73,20 @@ void Mifare::chk() void Mifare::nested() { - QString result = util->execCMDWithOutput("hf mf nested " + QString::number(cardType.type) + " *"); + QString result = util->execCMDWithOutput( + "hf mf nested " + QString::number(cardType.type) + " *"); int offset = 0; QString tmp; - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { - offset = result.indexOf(*nestedKeyPattern, offset); + offset = nestedKeyPattern->indexIn(result, offset); +// offset = result.indexOf(*nestedKeyPattern, offset); tmp = result.mid(offset, 47).toUpper(); offset += 47; - if(tmp.at(23) == '1') + if (tmp.at(23) == '1') keyAList->replace(i, tmp.mid(7, 12).trimmed()); - if(tmp.at(44) == '1') + if (tmp.at(44) == '1') keyBList->replace(i, tmp.mid(28, 12).trimmed()); } data_syncWithKeyWidget(); @@ -91,7 +96,7 @@ void Mifare::hardnested() { MF_Attack_hardnestedDialog dialog(cardType.blocks); connect(&dialog, &MF_Attack_hardnestedDialog::sendCMD, util, &Util::execCMD); - if(dialog.exec() == QDialog::Accepted) + if (dialog.exec() == QDialog::Accepted) ui->funcTab->setCurrentIndex(1); } @@ -111,30 +116,30 @@ void Mifare::read() { int waitTime = 300; int currblk = ui->MF_RW_blockBox->currentText().toInt(); - QString result = util->execCMDWithOutput("hf mf rdbl " - + QString::number(currblk) - + " " - + ui->MF_RW_keyTypeBox->currentText() - + " " - + ui->MF_RW_keyEdit->text(), waitTime); - if(result.indexOf("isOk:01") != -1) - { - result = result.mid(result.indexOf(*dataPattern, 0), 47).toUpper(); - if((currblk < 128 && ((currblk + 1) % 4 == 0)) || ((currblk + 1) % 8 == 0)) // process key block + QString result = util->execCMDWithOutput( + "hf mf rdbl " + QString::number(currblk) + " " + + ui->MF_RW_keyTypeBox->currentText() + " " + ui->MF_RW_keyEdit->text(), + waitTime); + if (result.indexOf("isOk:01") != -1) + { + result = result.mid(dataPattern->indexIn(result), 47).toUpper(); + if ((currblk < 128 && ((currblk + 1) % 4 == 0)) || + ((currblk + 1) % 8 == 0)) // process key block { - if(ui->MF_RW_keyTypeBox->currentText() == "A") + if (ui->MF_RW_keyTypeBox->currentText() == "A") { - for(int i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { - result = result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2)); + result = + result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2)); } ui->MF_RW_dataEdit->setText(result); QString tmpKey = result.right(18).replace(" ", ""); - result = util->execCMDWithOutput("hf mf rdbl " - + ui->MF_RW_keyTypeBox->currentText() - + " B " - + tmpKey, waitTime); - if(result.indexOf("isOk:01") == -1) + result = util->execCMDWithOutput( + "hf mf rdbl " + ui->MF_RW_keyTypeBox->currentText() + " B " + + tmpKey, + waitTime); + if (result.indexOf("isOk:01") == -1) { result = ui->MF_RW_dataEdit->text(); result = result.replace(30, 17, "?? ?? ?? ?? ?? ??"); @@ -143,9 +148,10 @@ void Mifare::read() } else { - for(int i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { - result = result.replace(30 + i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2)); + result = result.replace(30 + i * 3, 2, + ui->MF_RW_keyEdit->text().mid(i * 2, 2)); } result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? "); ui->MF_RW_dataEdit->setText(result); @@ -167,27 +173,27 @@ void Mifare::readAll() QString tmp; int offset = 0; - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { result = ""; isKeyAValid = false; isKeyBValid = false; // check keys and read the first block of each sector - if(data_isKeyValid(keyAList->at(i))) + if (data_isKeyValid(keyAList->at(i))) { - result = util->execCMDWithOutput("hf mf rdsc " - + QString::number(i) - + " A " - + keyAList->at(i), waitTime); + result = util->execCMDWithOutput("hf mf rdsc " + QString::number(i) + + " A " + keyAList->at(i), + waitTime); qDebug() << result; offset = result.indexOf("isOk:01"); - if(offset != -1) + if (offset != -1) { isKeyAValid = true; - for(int j = 0; j < cardType.blk[i]; j++) + for (int j = 0; j < cardType.blk[i]; j++) { - offset = result.indexOf(*dataPattern, offset); + offset = dataPattern->indexIn(result, offset); +// offset = result.indexOf(*dataPattern, offset); tmp = result.mid(offset, 47).toUpper(); offset += 47; qDebug() << tmp; @@ -197,20 +203,20 @@ void Mifare::readAll() } } } - if(data_isKeyValid(keyBList->at(i))) + if (data_isKeyValid(keyBList->at(i))) { - result = util->execCMDWithOutput("hf mf rdsc " - + QString::number(i) - + " B " - + keyBList->at(i), waitTime); + result = util->execCMDWithOutput("hf mf rdsc " + QString::number(i) + + " B " + keyBList->at(i), + waitTime); qDebug() << result; offset = result.indexOf("isOk:01"); - if(offset != -1) + if (offset != -1) { isKeyBValid = true; - for(int j = 0; j < cardType.blk[i]; j++) + for (int j = 0; j < cardType.blk[i]; j++) { - offset = result.indexOf(*dataPattern, offset); + offset = dataPattern->indexIn(result, offset); +// offset = result.indexOf(*dataPattern, offset); tmp = result.mid(offset, 47).toUpper(); offset += 47; qDebug() << tmp; @@ -221,18 +227,19 @@ void Mifare::readAll() } } - if(isKeyAValid || isKeyBValid) + if (isKeyAValid || isKeyBValid) { // fill the MF_dataWidget with the known valid key // // check whether the MF_dataWidget contains the valid key, - // and fill MF_keyWidget(when you only have KeyA but the ReadBlock output contains the KeyB) + // and fill MF_keyWidget(when you only have KeyA but the ReadBlock output + // contains the KeyB) // // the structure is not symmetric, since you cannot get KeyA from output // this program will only process the provided KeyA(in MF_keyWidget) result = dataList->at(cardType.blks[i] + cardType.blk[i] - 1); - if(isKeyAValid) + if (isKeyAValid) { result.replace(0, 12, keyAList->at(i)); } @@ -242,20 +249,22 @@ void Mifare::readAll() } dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result); - if(isKeyBValid) + if (isKeyBValid) { result.replace(20, 12, keyBList->at(i)); dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result); data_syncWithDataWidget(false, cardType.blks[i] + cardType.blk[i] - 1); } - else // now isKeyAValid == true, the output might contains the KeyB + else // now isKeyAValid == true, the output might contains the KeyB { - QString tmpKey = dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12); - result = util->execCMDWithOutput("hf mf rdbl " - + QString::number(cardType.blks[i] + cardType.blk[i] - 1) - + " B " - + tmpKey, waitTime); - if(result.indexOf("isOk:01") != -1) + QString tmpKey = + dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12); + result = util->execCMDWithOutput( + "hf mf rdbl " + + QString::number(cardType.blks[i] + cardType.blk[i] - 1) + + " B " + tmpKey, + waitTime); + if (result.indexOf("isOk:01") != -1) { keyBList->replace(i, tmpKey); data_syncWithKeyWidget(false, i, false); @@ -265,7 +274,6 @@ void Mifare::readAll() result = dataList->at(cardType.blks[i] + cardType.blk[i] - 1); result = result.replace(20, 12, "????????????"); dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result); - } } data_syncWithDataWidget(false, cardType.blks[i] + cardType.blk[i] - 1); @@ -276,15 +284,13 @@ void Mifare::readAll() void Mifare::write() { int waitTime = 300; - QString result = util->execCMDWithOutput("hf mf wrbl " - + ui->MF_RW_blockBox->currentText() - + " " - + ui->MF_RW_keyTypeBox->currentText() - + " " - + ui->MF_RW_keyEdit->text() - + " " - + ui->MF_RW_dataEdit->text().replace(" ", ""), waitTime); - if(result.indexOf("isOk:01") != -1) + QString result = util->execCMDWithOutput( + "hf mf wrbl " + ui->MF_RW_blockBox->currentText() + " " + + ui->MF_RW_keyTypeBox->currentText() + " " + + ui->MF_RW_keyEdit->text() + " " + + ui->MF_RW_dataEdit->text().replace(" ", ""), + waitTime); + if (result.indexOf("isOk:01") != -1) { QMessageBox::information(parent, tr("Info"), tr("Success!")); } @@ -298,31 +304,31 @@ void Mifare::writeAll() { const int waitTime = 300; QString result; - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { - for(int j = 0; j < cardType.blk[i]; j++) + for (int j = 0; j < cardType.blk[i]; j++) { - result = ""; // if the KeyA is invalid and the result is not empty, the KeyB will not be tested. - if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?')) + result = ""; // if the KeyA is invalid and the result is not empty, the + // KeyB will not be tested. + if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != + DATA_NOSPACE || + dataList->at(cardType.blks[i] + j).contains('?')) continue; - if(data_isKeyValid(keyAList->at(i))) + if (data_isKeyValid(keyAList->at(i))) { - result = util->execCMDWithOutput("hf mf wrbl " - + QString::number(cardType.blks[i] + j) - + " A " - + keyAList->at(i) - + " " - + dataList->at(cardType.blks[i] + j), waitTime); + result = util->execCMDWithOutput( + "hf mf wrbl " + QString::number(cardType.blks[i] + j) + " A " + + keyAList->at(i) + " " + dataList->at(cardType.blks[i] + j), + waitTime); } - qDebug() << i << j << result.indexOf("isOk:01") << data_isKeyValid(keyBList->at(i)); - if(result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i))) + qDebug() << i << j << result.indexOf("isOk:01") + << data_isKeyValid(keyBList->at(i)); + if (result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i))) { - result = util->execCMDWithOutput("hf mf wrbl " - + QString::number(cardType.blks[i] + j) - + " B " - + keyBList->at(i) - + " " - + dataList->at(cardType.blks[i] + j), waitTime); + result = util->execCMDWithOutput( + "hf mf wrbl " + QString::number(cardType.blks[i] + j) + " B " + + keyBList->at(i) + " " + dataList->at(cardType.blks[i] + j), + waitTime); } } } @@ -332,11 +338,11 @@ void Mifare::readC() { int waitTime = 300; int currblk = ui->MF_RW_blockBox->currentText().toInt(); - QString result = util->execCMDWithOutput("hf mf cgetblk " - + QString::number(currblk), waitTime); - if(result.indexOf("No chinese") == -1) + QString result = util->execCMDWithOutput( + "hf mf cgetblk " + QString::number(currblk), waitTime); + if (result.indexOf("No chinese") == -1) { - result = result.mid(result.indexOf(*dataPattern, 0), 47).toUpper(); + result = result.mid(dataPattern->indexIn(result), 47).toUpper(); ui->MF_RW_dataEdit->setText(result); } } @@ -348,17 +354,17 @@ void Mifare::readAllC() QString tmp; int offset = 0; - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { - result = util->execCMDWithOutput("hf mf cgetsc " - + QString::number(i), waitTime); + result = util->execCMDWithOutput("hf mf cgetsc " + QString::number(i), waitTime); qDebug() << result; - if(result.indexOf("No chinese") == -1) + if (result.indexOf("No chinese") == -1) { offset = 0; - for(int j = 0; j < cardType.blk[i]; j++) + for (int j = 0; j < cardType.blk[i]; j++) { - offset = result.indexOf(*dataPattern, offset); + offset = dataPattern->indexIn(result, offset); +// offset = result.indexOf(*dataPattern, offset); tmp = result.mid(offset, 47).toUpper(); offset += 47; qDebug() << tmp; @@ -366,8 +372,10 @@ void Mifare::readAllC() dataList->replace(cardType.blks[i] + j, tmp); data_syncWithDataWidget(false, cardType.blks[i] + j); } - keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); - keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); + keyAList->replace( + i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); + keyBList->replace( + i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); data_syncWithKeyWidget(false, i, true); data_syncWithKeyWidget(false, i, false); } @@ -377,11 +385,11 @@ void Mifare::readAllC() void Mifare::writeC() { int waitTime = 150; - QString result = util->execCMDWithOutput("hf mf csetblk " - + ui->MF_RW_blockBox->currentText() - + " " - + ui->MF_RW_dataEdit->text().replace(" ", ""), waitTime); - if(result.indexOf("No chinese") == -1) + QString result = util->execCMDWithOutput( + "hf mf csetblk " + ui->MF_RW_blockBox->currentText() + " " + + ui->MF_RW_dataEdit->text().replace(" ", ""), + waitTime); + if (result.indexOf("No chinese") == -1) { QMessageBox::information(parent, tr("Info"), tr("Success!")); } @@ -395,33 +403,32 @@ void Mifare::writeAllC() { const int waitTime = 150; QString result; - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { - for(int j = 0; j < cardType.blk[i]; j++) + for (int j = 0; j < cardType.blk[i]; j++) { - result = ""; // if the KeyA is invalid and the result is not empty, the KeyB will not be tested. - if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?')) + result = ""; + if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || + dataList->at(cardType.blks[i] + j).contains('?')) continue; - result = util->execCMDWithOutput("hf mf csetblk " - + QString::number(cardType.blks[i] + j) - + " " - + dataList->at(cardType.blks[i] + j), waitTime); + result = util->execCMDWithOutput( + "hf mf csetblk " + QString::number(cardType.blks[i] + j) + " " + + dataList->at(cardType.blks[i] + j), + waitTime); } } } void Mifare::wipeC() { - util->execCMD("hf mf cwipe " - + QString::number(cardType.type) - + " f"); + util->execCMD("hf mf cwipe " + QString::number(cardType.type) + " f"); ui->funcTab->setCurrentIndex(1); } void Mifare::setParameterC() { QString result = info(true); - if(result == "") + if (result == "") QMessageBox::information(parent, tr("Info"), tr("Failed to read card.")); else { @@ -429,9 +436,10 @@ void Mifare::setParameterC() lis[0].replace(" ", ""); lis[1].replace(" ", ""); lis[2].replace(" ", ""); - MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(), lis[2].mid(0, 2).toUpper()); + MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(), + lis[2].mid(0, 2).toUpper()); connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD); - if(dialog.exec() == QDialog::Accepted) + if (dialog.exec() == QDialog::Accepted) ui->funcTab->setCurrentIndex(1); } } @@ -442,10 +450,75 @@ void Mifare::lockC() util->execCMD("hf 14a raw -pa 43"); util->execCMD("hf 14a raw -pa E0 00 39 F7"); util->execCMD("hf 14a raw -pa E1 00 E1 EE"); - util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 18 47"); + util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 " + " 00 00 00 08 18 47"); util->execCMD("hf 14a raw 52"); } +void Mifare::writeAllE() +{ + const int waitTime = 200; + QString result; + for (int i = 0; i < cardType.sectors; i++) + { + for (int j = 0; j < cardType.blk[i]; j++) + { + result = ""; + if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?')) + continue; + result = util->execCMDWithOutput( + "hf mf eset " + QString::number(cardType.blks[i] + j) + + " " + + dataList->at(cardType.blks[i] + j), + waitTime); + } + } + util->execCMDWithOutput("hf mf eget", waitTime); // to refresh output buffer; +} + +void Mifare::readAllE() +{ + QString result; + const int waitTime = 200; + + QString tmp; + int offset = 0; + for (int i = 0; i < cardType.sectors; i++) + { + offset = 0; + for (int j = 0; j < cardType.blk[i]; j++) + { + + qDebug() << "**********" ; + result = util->execCMDWithOutput("hf mf eget " + QString::number(cardType.blks[i] + j), waitTime); + qDebug() << result ; + + offset = dataPattern->indexIn(result); +// offset = result.indexOf(*dataPattern, offset); // When I find the data position in this way, the Regex might fail to match. + + tmp = result.mid(offset, 47).toUpper(); + qDebug() << tmp << offset; + qDebug() << "**********" ; + + if(offset == -1) + continue; + tmp.replace(" ", ""); + dataList->replace(cardType.blks[i] + j, tmp); + data_syncWithDataWidget(false, cardType.blks[i] + j); + } + keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); + keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); + data_syncWithKeyWidget(false, i, true); + data_syncWithKeyWidget(false, i, false); + + } +} + +void Mifare::wipeE() +{ + util->execCMD("hf mf eclr"); +} + void Mifare::dump() { util->execCMD("hf mf dump"); @@ -461,15 +534,15 @@ void Mifare::restore() void Mifare::data_syncWithDataWidget(bool syncAll, int block) { QString tmp; - if(syncAll) + if (syncAll) { - for(int i = 0; i < cardType.blocks; i++) + for (int i = 0; i < cardType.blocks; i++) { tmp = ""; - if(dataList->at(i) != "") + if (dataList->at(i) != "") { tmp += dataList->at(i).mid(0, 2); - for(int j = 1; j < 16; j++) + for (int j = 1; j < 16; j++) { tmp += " "; tmp += dataList->at(i).mid(j * 2, 2); @@ -481,10 +554,10 @@ void Mifare::data_syncWithDataWidget(bool syncAll, int block) else { tmp = ""; - if(dataList->at(block) != "") + if (dataList->at(block) != "") { tmp += dataList->at(block).mid(0, 2); - for(int j = 1; j < 16; j++) + for (int j = 1; j < 16; j++) { tmp += " "; tmp += dataList->at(block).mid(j * 2, 2); @@ -496,9 +569,9 @@ void Mifare::data_syncWithDataWidget(bool syncAll, int block) void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) { - if(syncAll) + if (syncAll) { - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { ui->MF_keyWidget->item(i, 1)->setText(keyAList->at(i)); ui->MF_keyWidget->item(i, 2)->setText(keyBList->at(i)); @@ -506,7 +579,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) } else { - if(isKeyA) + if (isKeyA) ui->MF_keyWidget->item(sector, 1)->setText(keyAList->at(sector)); else ui->MF_keyWidget->item(sector, 2)->setText(keyBList->at(sector)); @@ -516,7 +589,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) void Mifare::data_clearData() { dataList->clear(); - for(int i = 0; i < cardType.blocks; i++) + for (int i = 0; i < cardType.blocks; i++) dataList->append(""); } @@ -524,49 +597,50 @@ void Mifare::data_clearKey() { keyAList->clear(); keyBList->clear(); - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { keyAList->append(""); keyBList->append(""); } } -bool Mifare::data_isKeyValid(const QString& key) +bool Mifare::data_isKeyValid(const QString &key) { - if(key.length() != 12) + if (key.length() != 12) return false; - for(int i = 0; i < 12; i++) + for (int i = 0; i < 12; i++) { - if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F'))) + if (!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F'))) return false; } return true; } -Mifare::DataType Mifare::data_isDataValid(QString data) // "?" will not been processd there +Mifare::DataType +Mifare::data_isDataValid(QString data) // "?" will not been processd there { - if(data.length() == 47) + if (data.length() == 47) { - for(int i = 0; i < 47; i++) + for (int i = 0; i < 47; i++) { - if(i % 3 != 0) + if (i % 3 != 0) { - if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) + if (!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) return DATA_INVALID; } else { - if(data[i] != ' ') + if (data[i] != ' ') return DATA_INVALID; } } return DATA_WITHSPACE; } - else if(data.length() == 32) + else if (data.length() == 32) { - for(int i = 0; i < 32; i++) + for (int i = 0; i < 32; i++) { - if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) + if (!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) return DATA_INVALID; } return DATA_NOSPACE; @@ -582,47 +656,43 @@ Mifare::CardType Mifare::getCardType() void Mifare::setCardType(int type) { - if(type == 0 || type == 1 || type == 2 || type == 4) + if (type == 0 || type == 1 || type == 2 || type == 4) { - if(type == 0) + if (type == 0) cardType = card_mini; - else if(type == 1) + else if (type == 1) cardType = card_1k; - else if(type == 2) + else if (type == 2) cardType = card_2k; - else if(type == 4) + else if (type == 4) cardType = card_4k; data_clearKey(); data_clearData(); } } -bool Mifare::data_loadDataFile(const QString& filename) +bool Mifare::data_loadDataFile(const QString &filename) { QFile file(filename, this); - if(file.open(QIODevice::ReadOnly)) + if (file.open(QIODevice::ReadOnly)) { QByteArray buff; buff = file.read(10000); bool isBin = false; - for(int i = 0; i < cardType.blocks * 16; i++) // Detect the file type + for (int i = 0; i < cardType.blocks * 16; i++) // Detect the file type { -// qDebug() << (unsigned char)buff[i]; - if(!((buff[i] >= 'A' && buff[i] <= 'F') || - (buff[i] >= 'a' && buff[i] <= 'f') || - (buff[i] >= '0' && buff[i] <= '9') || - buff[i] == '\n' || - buff[i] == '\r')) + // qDebug() << (unsigned char)buff[i]; + if (!((buff[i] >= 'A' && buff[i] <= 'F') || (buff[i] >= 'a' && buff[i] <= 'f') || (buff[i] >= '0' && buff[i] <= '9') || buff[i] == '\n' || buff[i] == '\r')) { isBin = true; break; } } - if(isBin) + if (isBin) { - if(file.size() < cardType.blocks * 16) + if (file.size() < cardType.blocks * 16) return false; - for(int i = 0; i < cardType.blocks; i++) + for (int i = 0; i < cardType.blocks; i++) { QString tmp = bin2text(buff, i, 16); dataList->replace(i, tmp.toUpper()); @@ -632,7 +702,7 @@ bool Mifare::data_loadDataFile(const QString& filename) { QString tmp = buff.left(cardType.blocks * 34); QStringList tmpList = tmp.split("\r\n"); - for(int i = 0; i < cardType.blocks; i++) + for (int i = 0; i < cardType.blocks; i++) { dataList->replace(i, tmpList[i].toUpper()); qDebug() << tmpList[i]; @@ -648,17 +718,17 @@ bool Mifare::data_loadDataFile(const QString& filename) } } -bool Mifare::data_loadKeyFile(const QString& filename) +bool Mifare::data_loadKeyFile(const QString &filename) { QFile file(filename, this); - if(file.open(QIODevice::ReadOnly)) + if (file.open(QIODevice::ReadOnly)) { QByteArray buff; buff = file.read(10000); bool isKey = file.size() <= cardType.sectors * 14; - if(isKey) + if (isKey) { - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { QString tmp = bin2text(buff, i, 12); keyAList->replace(i, tmp.left(12).toUpper()); @@ -667,7 +737,7 @@ bool Mifare::data_loadKeyFile(const QString& filename) } else { - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { int blk = cardType.blks[i] + cardType.blk[i] - 1; QString tmp = bin2text(buff, blk, 16); @@ -685,12 +755,14 @@ bool Mifare::data_loadKeyFile(const QString& filename) } } -QString Mifare::bin2text(const QByteArray& buff, int i, int length) +QString Mifare::bin2text(const QByteArray &buff, int i, int length) { QString ret = ""; char LByte, RByte; - char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - for(int j = 0; j < length; j++) + char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + for (int j = 0; j < length; j++) { LByte = map[(unsigned char)buff[i * length + j] >> 4]; RByte = map[(unsigned char)buff[i * length + j] & 0xF]; @@ -701,26 +773,26 @@ QString Mifare::bin2text(const QByteArray& buff, int i, int length) return ret; } -bool Mifare::data_saveDataFile(const QString& filename, bool isBin) +bool Mifare::data_saveDataFile(const QString &filename, bool isBin) { QFile file(filename, this); - if(file.open(QIODevice::WriteOnly)) + if (file.open(QIODevice::WriteOnly)) { QByteArray buff; QChar tmp; - if(isBin) + if (isBin) { - for(int i = 0; i < cardType.blocks; i++) + for (int i = 0; i < cardType.blocks; i++) { - for(int j = 0; j < 16; j++) + for (int j = 0; j < 16; j++) { unsigned char Byt[2]; - for(int k = 0; k < 2; k++) + for (int k = 0; k < 2; k++) { tmp = dataList->at(i).at(j * 2 + k).toUpper(); - if(tmp >= '0' && tmp <= '9') + if (tmp >= '0' && tmp <= '9') Byt[k] = tmp.toLatin1() - '0'; - else if(tmp >= 'A' && tmp <= 'F') + else if (tmp >= 'A' && tmp <= 'F') Byt[k] = tmp.toLatin1() - 'A' + 10; } buff += (Byt[0] << 4) | Byt[1]; @@ -729,7 +801,7 @@ bool Mifare::data_saveDataFile(const QString& filename, bool isBin) } else { - for(int i = 0; i < cardType.blocks; i++) + for (int i = 0; i < cardType.blocks; i++) { buff += dataList->at(i); buff += "\r\n"; @@ -745,39 +817,39 @@ bool Mifare::data_saveDataFile(const QString& filename, bool isBin) } } -bool Mifare::data_saveKeyFile(const QString& filename, bool isBin) +bool Mifare::data_saveKeyFile(const QString &filename, bool isBin) { QFile file(filename, this); - if(file.open(QIODevice::WriteOnly)) + if (file.open(QIODevice::WriteOnly)) { QByteArray buff; QChar tmp; - if(isBin) + if (isBin) { - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { - for(int j = 0; j < 6; j++) + for (int j = 0; j < 6; j++) { unsigned char Byt[2]; - for(int k = 0; k < 2; k++) + for (int k = 0; k < 2; k++) { tmp = keyAList->at(i).at(j * 2 + k).toUpper(); - if(tmp >= '0' && tmp <= '9') + if (tmp >= '0' && tmp <= '9') Byt[k] = tmp.toLatin1() - '0'; - else if(tmp >= 'A' && tmp <= 'F') + else if (tmp >= 'A' && tmp <= 'F') Byt[k] = tmp.toLatin1() - 'A' + 10; } buff += (Byt[0] << 4) | Byt[1]; } - for(int j = 0; j < 6; j++) + for (int j = 0; j < 6; j++) { unsigned char Byt[2]; - for(int k = 0; k < 2; k++) + for (int k = 0; k < 2; k++) { tmp = keyBList->at(i).at(j * 2 + k).toUpper(); - if(tmp >= '0' && tmp <= '9') + if (tmp >= '0' && tmp <= '9') Byt[k] = tmp.toLatin1() - '0'; - else if(tmp >= 'A' && tmp <= 'F') + else if (tmp >= 'A' && tmp <= 'F') Byt[k] = tmp.toLatin1() - 'A' + 10; } buff += (Byt[0] << 4) | Byt[1]; @@ -786,7 +858,6 @@ bool Mifare::data_saveKeyFile(const QString& filename, bool isBin) } else { - } bool ret = file.write(buff) != -1; file.close(); @@ -800,20 +871,20 @@ bool Mifare::data_saveKeyFile(const QString& filename, bool isBin) void Mifare::data_key2Data() { - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { QString tmp = ""; - if(data_isKeyValid(keyAList->at(i))) + if (data_isKeyValid(keyAList->at(i))) tmp += keyAList->at(i); else tmp += "????????????"; - if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") + if (dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") tmp += "FF078069"; // default control bytes else tmp += dataList->at(cardType.blks[i] + cardType.blk[i] - 1).mid(12, 8); - if(data_isKeyValid(keyBList->at(i))) + if (data_isKeyValid(keyBList->at(i))) tmp += keyBList->at(i); else tmp += "????????????"; @@ -825,30 +896,32 @@ void Mifare::data_key2Data() void Mifare::data_data2Key() { - for(int i = 0; i < cardType.sectors; i++) + for (int i = 0; i < cardType.sectors; i++) { - if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") + if (dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") { keyAList->replace(i, "????????????"); keyBList->replace(i, "????????????"); } else { - keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); - keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); + keyAList->replace( + i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); + keyBList->replace( + i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); } data_syncWithKeyWidget(); } } -void Mifare::data_setData(int block, const QString& data) +void Mifare::data_setData(int block, const QString &data) { dataList->replace(block, data); } -void Mifare::data_setKey(int sector, bool isKeyA, const QString& key) +void Mifare::data_setKey(int sector, bool isKeyA, const QString &key) { - if(isKeyA) + if (isKeyA) keyAList->replace(sector, key); else keyBList->replace(sector, key); diff --git a/module/mifare.h b/module/mifare.h index 8f31ead..1c0926c 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -105,6 +105,9 @@ public: void data_setData(int block, const QString &data); void data_setKey(int sector, bool isKeyA, const QString &key); void lockC(); + void writeAllE(); + void readAllE(); + void wipeE(); public slots: signals: diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 600aec1..19ce5c0 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -6,10 +6,11 @@ MainWindow::MainWindow(QWidget *parent) , ui(new Ui::MainWindow) { ui->setupUi(this); - ui->MF_simGroupBox->setVisible(false); // developing... +// ui->MF_simGroupBox->setVisible(false); // developing... ui->MF_sniffGroupBox->setVisible(false); // developing... myInfo = new QAction("wh201906", this); - connect(myInfo, &QAction::triggered, [ = ]() { + connect(myInfo, &QAction::triggered, [ = ]() + { QDesktopServices::openUrl(QUrl("https://github.com/wh201906")); }); this->addAction(myInfo); @@ -473,6 +474,25 @@ void MainWindow::on_MF_UID_lockButton_clicked() mifare->lockC(); } +void MainWindow::on_MF_Sim_loadDataButton_clicked() +{ + setState(false); + mifare->writeAllE(); + setState(true); +} + +void MainWindow::on_MF_Sim_writeAllButton_clicked() +{ + setState(false); + mifare->readAllE(); + setState(true); +} + +void MainWindow::on_MF_Sim_clearButton_clicked() +{ + mifare->wipeE(); +} + void MainWindow::on_MF_Sniff_sniffButton_clicked() { setState(false); @@ -651,3 +671,5 @@ void MainWindow::setState(bool st) } // *********************************************** + + diff --git a/ui/mainwindow.h b/ui/mainwindow.h index 17dcf8f..5ecf277 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -22,7 +22,8 @@ #include "common/util.h" QT_BEGIN_NAMESPACE -namespace Ui { +namespace Ui +{ class MainWindow; } QT_END_NAMESPACE @@ -119,6 +120,12 @@ private slots: void on_MF_UID_lockButton_clicked(); + void on_MF_Sim_loadDataButton_clicked(); + + void on_MF_Sim_writeAllButton_clicked(); + + void on_MF_Sim_clearButton_clicked(); + private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 9e0722d..94e2915 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -105,9 +105,6 @@ 0 - - 1 - Mifare From 0995e529adaaa4b114c6eed75389a31c808cbe58 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Thu, 30 Apr 2020 21:00:57 +0800 Subject: [PATCH 2/7] Reformat --- module/mifare.cpp | 361 +++++++++++++++++++++++++--------------------- ui/mainwindow.cpp | 4 +- 2 files changed, 197 insertions(+), 168 deletions(-) diff --git a/module/mifare.cpp b/module/mifare.cpp index 642aca4..0ff483e 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -1,7 +1,6 @@ #include "mifare.h" -Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent) - : QObject(parent) +Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent): QObject(parent) { this->parent = parent; util = addr; @@ -19,17 +18,16 @@ Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent) QString Mifare::info(bool isRequiringOutput) { - if (isRequiringOutput) + if(isRequiringOutput) { QString result = util->execCMDWithOutput("hf 14a info", 500); - qDebug() << result - << result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0); + qDebug() << result << result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0); result.replace("UID :", "|"); result.replace("ATQA :", "|"); result.replace("SAK :", "|"); result.replace("TYPE :", "|"); QStringList lis = result.split("|"); - if (lis.length() > 4) + if(lis.length() > 4) { qDebug() << lis[1] + lis[2] + lis[3]; return lis[1] + lis[2] + lis[3]; @@ -48,13 +46,15 @@ QString Mifare::info(bool isRequiringOutput) void Mifare::chk() { QString result = util->execCMDWithOutput( - "hf mf chk *" + QString::number(cardType.type) + " ?", + "hf mf chk *" + + QString::number(cardType.type) + + " ?", 1000 + cardType.type * 1000); qDebug() << result; int offset = 0; QString tmp, tmp2; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { offset = chkKeyPattern->indexIn(result, offset); // offset = result.indexOf(*chkKeyPattern, offset); @@ -62,10 +62,10 @@ void Mifare::chk() offset += 39; qDebug() << tmp << offset; tmp2 = tmp.mid(7, 12).trimmed(); - if (tmp2 != "?") + if(tmp2 != "?") keyAList->replace(i, tmp2); tmp2 = tmp.mid(24, 12).trimmed(); - if (tmp2 != "?") + if(tmp2 != "?") keyBList->replace(i, tmp2); } data_syncWithKeyWidget(); @@ -74,19 +74,21 @@ void Mifare::chk() void Mifare::nested() { QString result = util->execCMDWithOutput( - "hf mf nested " + QString::number(cardType.type) + " *"); + "hf mf nested " + + QString::number(cardType.type) + + " *"); int offset = 0; QString tmp; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { offset = nestedKeyPattern->indexIn(result, offset); // offset = result.indexOf(*nestedKeyPattern, offset); tmp = result.mid(offset, 47).toUpper(); offset += 47; - if (tmp.at(23) == '1') + if(tmp.at(23) == '1') keyAList->replace(i, tmp.mid(7, 12).trimmed()); - if (tmp.at(44) == '1') + if(tmp.at(44) == '1') keyBList->replace(i, tmp.mid(28, 12).trimmed()); } data_syncWithKeyWidget(); @@ -96,7 +98,7 @@ void Mifare::hardnested() { MF_Attack_hardnestedDialog dialog(cardType.blocks); connect(&dialog, &MF_Attack_hardnestedDialog::sendCMD, util, &Util::execCMD); - if (dialog.exec() == QDialog::Accepted) + if(dialog.exec() == QDialog::Accepted) ui->funcTab->setCurrentIndex(1); } @@ -117,29 +119,33 @@ void Mifare::read() int waitTime = 300; int currblk = ui->MF_RW_blockBox->currentText().toInt(); QString result = util->execCMDWithOutput( - "hf mf rdbl " + QString::number(currblk) + " " + - ui->MF_RW_keyTypeBox->currentText() + " " + ui->MF_RW_keyEdit->text(), + "hf mf rdbl " + + QString::number(currblk) + + " " + + ui->MF_RW_keyTypeBox->currentText() + + " " + + ui->MF_RW_keyEdit->text(), waitTime); - if (result.indexOf("isOk:01") != -1) + if(result.indexOf("isOk:01") != -1) { result = result.mid(dataPattern->indexIn(result), 47).toUpper(); - if ((currblk < 128 && ((currblk + 1) % 4 == 0)) || - ((currblk + 1) % 8 == 0)) // process key block + if((currblk < 128 && ((currblk + 1) % 4 == 0)) || ((currblk + 1) % 8 == 0)) // process key block { - if (ui->MF_RW_keyTypeBox->currentText() == "A") + if(ui->MF_RW_keyTypeBox->currentText() == "A") { - for (int i = 0; i < 6; i++) + for(int i = 0; i < 6; i++) { - result = - result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2)); + result = result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2)); } ui->MF_RW_dataEdit->setText(result); QString tmpKey = result.right(18).replace(" ", ""); result = util->execCMDWithOutput( - "hf mf rdbl " + ui->MF_RW_keyTypeBox->currentText() + " B " + - tmpKey, + "hf mf rdbl " + + ui->MF_RW_keyTypeBox->currentText() + + " B " + + tmpKey, waitTime); - if (result.indexOf("isOk:01") == -1) + if(result.indexOf("isOk:01") == -1) { result = ui->MF_RW_dataEdit->text(); result = result.replace(30, 17, "?? ?? ?? ?? ?? ??"); @@ -148,10 +154,12 @@ void Mifare::read() } else { - for (int i = 0; i < 6; i++) + for(int i = 0; i < 6; i++) { - result = result.replace(30 + i * 3, 2, - ui->MF_RW_keyEdit->text().mid(i * 2, 2)); + result = result.replace( + 30 + i * 3, + 2, + ui->MF_RW_keyEdit->text().mid(i * 2, 2)); } result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? "); ui->MF_RW_dataEdit->setText(result); @@ -173,24 +181,27 @@ void Mifare::readAll() QString tmp; int offset = 0; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { result = ""; isKeyAValid = false; isKeyBValid = false; // check keys and read the first block of each sector - if (data_isKeyValid(keyAList->at(i))) + if(data_isKeyValid(keyAList->at(i))) { - result = util->execCMDWithOutput("hf mf rdsc " + QString::number(i) + - " A " + keyAList->at(i), - waitTime); + result = util->execCMDWithOutput( + "hf mf rdsc " + + QString::number(i) + + " A " + + keyAList->at(i), + waitTime); qDebug() << result; offset = result.indexOf("isOk:01"); - if (offset != -1) + if(offset != -1) { isKeyAValid = true; - for (int j = 0; j < cardType.blk[i]; j++) + for(int j = 0; j < cardType.blk[i]; j++) { offset = dataPattern->indexIn(result, offset); // offset = result.indexOf(*dataPattern, offset); @@ -203,17 +214,20 @@ void Mifare::readAll() } } } - if (data_isKeyValid(keyBList->at(i))) + if(data_isKeyValid(keyBList->at(i))) { - result = util->execCMDWithOutput("hf mf rdsc " + QString::number(i) + - " B " + keyBList->at(i), - waitTime); + result = util->execCMDWithOutput( + "hf mf rdsc " + + QString::number(i) + + " B " + + keyBList->at(i), + waitTime); qDebug() << result; offset = result.indexOf("isOk:01"); - if (offset != -1) + if(offset != -1) { isKeyBValid = true; - for (int j = 0; j < cardType.blk[i]; j++) + for(int j = 0; j < cardType.blk[i]; j++) { offset = dataPattern->indexIn(result, offset); // offset = result.indexOf(*dataPattern, offset); @@ -227,7 +241,7 @@ void Mifare::readAll() } } - if (isKeyAValid || isKeyBValid) + if(isKeyAValid || isKeyBValid) { // fill the MF_dataWidget with the known valid key @@ -239,7 +253,7 @@ void Mifare::readAll() // the structure is not symmetric, since you cannot get KeyA from output // this program will only process the provided KeyA(in MF_keyWidget) result = dataList->at(cardType.blks[i] + cardType.blk[i] - 1); - if (isKeyAValid) + if(isKeyAValid) { result.replace(0, 12, keyAList->at(i)); } @@ -249,7 +263,7 @@ void Mifare::readAll() } dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result); - if (isKeyBValid) + if(isKeyBValid) { result.replace(20, 12, keyBList->at(i)); dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result); @@ -260,11 +274,12 @@ void Mifare::readAll() QString tmpKey = dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12); result = util->execCMDWithOutput( - "hf mf rdbl " + - QString::number(cardType.blks[i] + cardType.blk[i] - 1) + - " B " + tmpKey, + "hf mf rdbl " + + QString::number(cardType.blks[i] + cardType.blk[i] - 1) + + " B " + + tmpKey, waitTime); - if (result.indexOf("isOk:01") != -1) + if(result.indexOf("isOk:01") != -1) { keyBList->replace(i, tmpKey); data_syncWithKeyWidget(false, i, false); @@ -290,7 +305,7 @@ void Mifare::write() ui->MF_RW_keyEdit->text() + " " + ui->MF_RW_dataEdit->text().replace(" ", ""), waitTime); - if (result.indexOf("isOk:01") != -1) + if(result.indexOf("isOk:01") != -1) { QMessageBox::information(parent, tr("Info"), tr("Success!")); } @@ -304,30 +319,35 @@ void Mifare::writeAll() { const int waitTime = 300; QString result; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { - for (int j = 0; j < cardType.blk[i]; j++) + for(int j = 0; j < cardType.blk[i]; j++) { result = ""; // if the KeyA is invalid and the result is not empty, the // KeyB will not be tested. - if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != - DATA_NOSPACE || - dataList->at(cardType.blks[i] + j).contains('?')) + if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?')) continue; - if (data_isKeyValid(keyAList->at(i))) + if(data_isKeyValid(keyAList->at(i))) { result = util->execCMDWithOutput( - "hf mf wrbl " + QString::number(cardType.blks[i] + j) + " A " + - keyAList->at(i) + " " + dataList->at(cardType.blks[i] + j), + "hf mf wrbl " + + QString::number(cardType.blks[i] + j) + + " A " + + keyAList->at(i) + + " " + + dataList->at(cardType.blks[i] + j), waitTime); } - qDebug() << i << j << result.indexOf("isOk:01") - << data_isKeyValid(keyBList->at(i)); - if (result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i))) + qDebug() << i << j << result.indexOf("isOk:01") << data_isKeyValid(keyBList->at(i)); + if(result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i))) { result = util->execCMDWithOutput( - "hf mf wrbl " + QString::number(cardType.blks[i] + j) + " B " + - keyBList->at(i) + " " + dataList->at(cardType.blks[i] + j), + "hf mf wrbl " + + QString::number(cardType.blks[i] + j) + + " B " + + keyBList->at(i) + + " " + + dataList->at(cardType.blks[i] + j), waitTime); } } @@ -339,8 +359,10 @@ void Mifare::readC() int waitTime = 300; int currblk = ui->MF_RW_blockBox->currentText().toInt(); QString result = util->execCMDWithOutput( - "hf mf cgetblk " + QString::number(currblk), waitTime); - if (result.indexOf("No chinese") == -1) + "hf mf cgetblk " + + QString::number(currblk), + waitTime); + if(result.indexOf("No chinese") == -1) { result = result.mid(dataPattern->indexIn(result), 47).toUpper(); ui->MF_RW_dataEdit->setText(result); @@ -354,14 +376,17 @@ void Mifare::readAllC() QString tmp; int offset = 0; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { - result = util->execCMDWithOutput("hf mf cgetsc " + QString::number(i), waitTime); + result = util->execCMDWithOutput( + "hf mf cgetsc " + + QString::number(i), + waitTime); qDebug() << result; - if (result.indexOf("No chinese") == -1) + if(result.indexOf("No chinese") == -1) { offset = 0; - for (int j = 0; j < cardType.blk[i]; j++) + for(int j = 0; j < cardType.blk[i]; j++) { offset = dataPattern->indexIn(result, offset); // offset = result.indexOf(*dataPattern, offset); @@ -372,10 +397,8 @@ void Mifare::readAllC() dataList->replace(cardType.blks[i] + j, tmp); data_syncWithDataWidget(false, cardType.blks[i] + j); } - keyAList->replace( - i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); - keyBList->replace( - i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); + keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); + keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); data_syncWithKeyWidget(false, i, true); data_syncWithKeyWidget(false, i, false); } @@ -386,10 +409,12 @@ void Mifare::writeC() { int waitTime = 150; QString result = util->execCMDWithOutput( - "hf mf csetblk " + ui->MF_RW_blockBox->currentText() + " " + - ui->MF_RW_dataEdit->text().replace(" ", ""), + "hf mf csetblk " + + ui->MF_RW_blockBox->currentText() + + " " + + ui->MF_RW_dataEdit->text().replace(" ", ""), waitTime); - if (result.indexOf("No chinese") == -1) + if(result.indexOf("No chinese") == -1) { QMessageBox::information(parent, tr("Info"), tr("Success!")); } @@ -403,17 +428,18 @@ void Mifare::writeAllC() { const int waitTime = 150; QString result; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { - for (int j = 0; j < cardType.blk[i]; j++) + for(int j = 0; j < cardType.blk[i]; j++) { result = ""; - if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || - dataList->at(cardType.blks[i] + j).contains('?')) + if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?')) continue; result = util->execCMDWithOutput( - "hf mf csetblk " + QString::number(cardType.blks[i] + j) + " " + - dataList->at(cardType.blks[i] + j), + "hf mf csetblk " + + QString::number(cardType.blks[i] + j) + + " " + + dataList->at(cardType.blks[i] + j), waitTime); } } @@ -421,14 +447,17 @@ void Mifare::writeAllC() void Mifare::wipeC() { - util->execCMD("hf mf cwipe " + QString::number(cardType.type) + " f"); + util->execCMD( + "hf mf cwipe " + + QString::number(cardType.type) + + " f"); ui->funcTab->setCurrentIndex(1); } void Mifare::setParameterC() { QString result = info(true); - if (result == "") + if(result == "") QMessageBox::information(parent, tr("Info"), tr("Failed to read card.")); else { @@ -436,10 +465,9 @@ void Mifare::setParameterC() lis[0].replace(" ", ""); lis[1].replace(" ", ""); lis[2].replace(" ", ""); - MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(), - lis[2].mid(0, 2).toUpper()); + MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(), lis[2].mid(0, 2).toUpper()); connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD); - if (dialog.exec() == QDialog::Accepted) + if(dialog.exec() == QDialog::Accepted) ui->funcTab->setCurrentIndex(1); } } @@ -450,8 +478,7 @@ void Mifare::lockC() util->execCMD("hf 14a raw -pa 43"); util->execCMD("hf 14a raw -pa E0 00 39 F7"); util->execCMD("hf 14a raw -pa E1 00 E1 EE"); - util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 " - " 00 00 00 08 18 47"); + util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 18 47"); util->execCMD("hf 14a raw 52"); } @@ -459,15 +486,16 @@ void Mifare::writeAllE() { const int waitTime = 200; QString result; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { - for (int j = 0; j < cardType.blk[i]; j++) + for(int j = 0; j < cardType.blk[i]; j++) { result = ""; - if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?')) + if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?')) continue; result = util->execCMDWithOutput( - "hf mf eset " + QString::number(cardType.blks[i] + j) + "hf mf eset " + + QString::number(cardType.blks[i] + j) + " " + dataList->at(cardType.blks[i] + j), waitTime); @@ -483,14 +511,17 @@ void Mifare::readAllE() QString tmp; int offset = 0; - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { offset = 0; - for (int j = 0; j < cardType.blk[i]; j++) + for(int j = 0; j < cardType.blk[i]; j++) { qDebug() << "**********" ; - result = util->execCMDWithOutput("hf mf eget " + QString::number(cardType.blks[i] + j), waitTime); + result = util->execCMDWithOutput( + "hf mf eget " + + QString::number(cardType.blks[i] + j), + waitTime); qDebug() << result ; offset = dataPattern->indexIn(result); @@ -534,15 +565,15 @@ void Mifare::restore() void Mifare::data_syncWithDataWidget(bool syncAll, int block) { QString tmp; - if (syncAll) + if(syncAll) { - for (int i = 0; i < cardType.blocks; i++) + for(int i = 0; i < cardType.blocks; i++) { tmp = ""; - if (dataList->at(i) != "") + if(dataList->at(i) != "") { tmp += dataList->at(i).mid(0, 2); - for (int j = 1; j < 16; j++) + for(int j = 1; j < 16; j++) { tmp += " "; tmp += dataList->at(i).mid(j * 2, 2); @@ -554,10 +585,10 @@ void Mifare::data_syncWithDataWidget(bool syncAll, int block) else { tmp = ""; - if (dataList->at(block) != "") + if(dataList->at(block) != "") { tmp += dataList->at(block).mid(0, 2); - for (int j = 1; j < 16; j++) + for(int j = 1; j < 16; j++) { tmp += " "; tmp += dataList->at(block).mid(j * 2, 2); @@ -569,9 +600,9 @@ void Mifare::data_syncWithDataWidget(bool syncAll, int block) void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) { - if (syncAll) + if(syncAll) { - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { ui->MF_keyWidget->item(i, 1)->setText(keyAList->at(i)); ui->MF_keyWidget->item(i, 2)->setText(keyBList->at(i)); @@ -579,7 +610,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) } else { - if (isKeyA) + if(isKeyA) ui->MF_keyWidget->item(sector, 1)->setText(keyAList->at(sector)); else ui->MF_keyWidget->item(sector, 2)->setText(keyBList->at(sector)); @@ -589,7 +620,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) void Mifare::data_clearData() { dataList->clear(); - for (int i = 0; i < cardType.blocks; i++) + for(int i = 0; i < cardType.blocks; i++) dataList->append(""); } @@ -597,7 +628,7 @@ void Mifare::data_clearKey() { keyAList->clear(); keyBList->clear(); - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { keyAList->append(""); keyBList->append(""); @@ -606,11 +637,11 @@ void Mifare::data_clearKey() bool Mifare::data_isKeyValid(const QString &key) { - if (key.length() != 12) + if(key.length() != 12) return false; - for (int i = 0; i < 12; i++) + for(int i = 0; i < 12; i++) { - if (!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F'))) + if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F'))) return false; } return true; @@ -619,28 +650,28 @@ bool Mifare::data_isKeyValid(const QString &key) Mifare::DataType Mifare::data_isDataValid(QString data) // "?" will not been processd there { - if (data.length() == 47) + if(data.length() == 47) { - for (int i = 0; i < 47; i++) + for(int i = 0; i < 47; i++) { - if (i % 3 != 0) + if(i % 3 != 0) { - if (!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) + if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) return DATA_INVALID; } else { - if (data[i] != ' ') + if(data[i] != ' ') return DATA_INVALID; } } return DATA_WITHSPACE; } - else if (data.length() == 32) + else if(data.length() == 32) { - for (int i = 0; i < 32; i++) + for(int i = 0; i < 32; i++) { - if (!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) + if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?')) return DATA_INVALID; } return DATA_NOSPACE; @@ -656,15 +687,15 @@ Mifare::CardType Mifare::getCardType() void Mifare::setCardType(int type) { - if (type == 0 || type == 1 || type == 2 || type == 4) + if(type == 0 || type == 1 || type == 2 || type == 4) { - if (type == 0) + if(type == 0) cardType = card_mini; - else if (type == 1) + else if(type == 1) cardType = card_1k; - else if (type == 2) + else if(type == 2) cardType = card_2k; - else if (type == 4) + else if(type == 4) cardType = card_4k; data_clearKey(); data_clearData(); @@ -674,25 +705,25 @@ void Mifare::setCardType(int type) bool Mifare::data_loadDataFile(const QString &filename) { QFile file(filename, this); - if (file.open(QIODevice::ReadOnly)) + if(file.open(QIODevice::ReadOnly)) { QByteArray buff; buff = file.read(10000); bool isBin = false; - for (int i = 0; i < cardType.blocks * 16; i++) // Detect the file type + for(int i = 0; i < cardType.blocks * 16; i++) // Detect the file type { // qDebug() << (unsigned char)buff[i]; - if (!((buff[i] >= 'A' && buff[i] <= 'F') || (buff[i] >= 'a' && buff[i] <= 'f') || (buff[i] >= '0' && buff[i] <= '9') || buff[i] == '\n' || buff[i] == '\r')) + if(!((buff[i] >= 'A' && buff[i] <= 'F') || (buff[i] >= 'a' && buff[i] <= 'f') || (buff[i] >= '0' && buff[i] <= '9') || buff[i] == '\n' || buff[i] == '\r')) { isBin = true; break; } } - if (isBin) + if(isBin) { - if (file.size() < cardType.blocks * 16) + if(file.size() < cardType.blocks * 16) return false; - for (int i = 0; i < cardType.blocks; i++) + for(int i = 0; i < cardType.blocks; i++) { QString tmp = bin2text(buff, i, 16); dataList->replace(i, tmp.toUpper()); @@ -702,7 +733,7 @@ bool Mifare::data_loadDataFile(const QString &filename) { QString tmp = buff.left(cardType.blocks * 34); QStringList tmpList = tmp.split("\r\n"); - for (int i = 0; i < cardType.blocks; i++) + for(int i = 0; i < cardType.blocks; i++) { dataList->replace(i, tmpList[i].toUpper()); qDebug() << tmpList[i]; @@ -721,14 +752,14 @@ bool Mifare::data_loadDataFile(const QString &filename) bool Mifare::data_loadKeyFile(const QString &filename) { QFile file(filename, this); - if (file.open(QIODevice::ReadOnly)) + if(file.open(QIODevice::ReadOnly)) { QByteArray buff; buff = file.read(10000); bool isKey = file.size() <= cardType.sectors * 14; - if (isKey) + if(isKey) { - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { QString tmp = bin2text(buff, i, 12); keyAList->replace(i, tmp.left(12).toUpper()); @@ -737,7 +768,7 @@ bool Mifare::data_loadKeyFile(const QString &filename) } else { - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { int blk = cardType.blks[i] + cardType.blk[i] - 1; QString tmp = bin2text(buff, blk, 16); @@ -762,7 +793,7 @@ QString Mifare::bin2text(const QByteArray &buff, int i, int length) char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - for (int j = 0; j < length; j++) + for(int j = 0; j < length; j++) { LByte = map[(unsigned char)buff[i * length + j] >> 4]; RByte = map[(unsigned char)buff[i * length + j] & 0xF]; @@ -776,23 +807,23 @@ QString Mifare::bin2text(const QByteArray &buff, int i, int length) bool Mifare::data_saveDataFile(const QString &filename, bool isBin) { QFile file(filename, this); - if (file.open(QIODevice::WriteOnly)) + if(file.open(QIODevice::WriteOnly)) { QByteArray buff; QChar tmp; - if (isBin) + if(isBin) { - for (int i = 0; i < cardType.blocks; i++) + for(int i = 0; i < cardType.blocks; i++) { - for (int j = 0; j < 16; j++) + for(int j = 0; j < 16; j++) { unsigned char Byt[2]; - for (int k = 0; k < 2; k++) + for(int k = 0; k < 2; k++) { tmp = dataList->at(i).at(j * 2 + k).toUpper(); - if (tmp >= '0' && tmp <= '9') + if(tmp >= '0' && tmp <= '9') Byt[k] = tmp.toLatin1() - '0'; - else if (tmp >= 'A' && tmp <= 'F') + else if(tmp >= 'A' && tmp <= 'F') Byt[k] = tmp.toLatin1() - 'A' + 10; } buff += (Byt[0] << 4) | Byt[1]; @@ -801,7 +832,7 @@ bool Mifare::data_saveDataFile(const QString &filename, bool isBin) } else { - for (int i = 0; i < cardType.blocks; i++) + for(int i = 0; i < cardType.blocks; i++) { buff += dataList->at(i); buff += "\r\n"; @@ -820,36 +851,36 @@ bool Mifare::data_saveDataFile(const QString &filename, bool isBin) bool Mifare::data_saveKeyFile(const QString &filename, bool isBin) { QFile file(filename, this); - if (file.open(QIODevice::WriteOnly)) + if(file.open(QIODevice::WriteOnly)) { QByteArray buff; QChar tmp; - if (isBin) + if(isBin) { - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { - for (int j = 0; j < 6; j++) + for(int j = 0; j < 6; j++) { unsigned char Byt[2]; - for (int k = 0; k < 2; k++) + for(int k = 0; k < 2; k++) { tmp = keyAList->at(i).at(j * 2 + k).toUpper(); - if (tmp >= '0' && tmp <= '9') + if(tmp >= '0' && tmp <= '9') Byt[k] = tmp.toLatin1() - '0'; - else if (tmp >= 'A' && tmp <= 'F') + else if(tmp >= 'A' && tmp <= 'F') Byt[k] = tmp.toLatin1() - 'A' + 10; } buff += (Byt[0] << 4) | Byt[1]; } - for (int j = 0; j < 6; j++) + for(int j = 0; j < 6; j++) { unsigned char Byt[2]; - for (int k = 0; k < 2; k++) + for(int k = 0; k < 2; k++) { tmp = keyBList->at(i).at(j * 2 + k).toUpper(); - if (tmp >= '0' && tmp <= '9') + if(tmp >= '0' && tmp <= '9') Byt[k] = tmp.toLatin1() - '0'; - else if (tmp >= 'A' && tmp <= 'F') + else if(tmp >= 'A' && tmp <= 'F') Byt[k] = tmp.toLatin1() - 'A' + 10; } buff += (Byt[0] << 4) | Byt[1]; @@ -871,20 +902,20 @@ bool Mifare::data_saveKeyFile(const QString &filename, bool isBin) void Mifare::data_key2Data() { - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { QString tmp = ""; - if (data_isKeyValid(keyAList->at(i))) + if(data_isKeyValid(keyAList->at(i))) tmp += keyAList->at(i); else tmp += "????????????"; - if (dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") + if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") tmp += "FF078069"; // default control bytes else tmp += dataList->at(cardType.blks[i] + cardType.blk[i] - 1).mid(12, 8); - if (data_isKeyValid(keyBList->at(i))) + if(data_isKeyValid(keyBList->at(i))) tmp += keyBList->at(i); else tmp += "????????????"; @@ -896,19 +927,17 @@ void Mifare::data_key2Data() void Mifare::data_data2Key() { - for (int i = 0; i < cardType.sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { - if (dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") + if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") { keyAList->replace(i, "????????????"); keyBList->replace(i, "????????????"); } else { - keyAList->replace( - i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); - keyBList->replace( - i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); + keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); + keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); } data_syncWithKeyWidget(); } @@ -921,7 +950,7 @@ void Mifare::data_setData(int block, const QString &data) void Mifare::data_setKey(int sector, bool isKeyA, const QString &key) { - if (isKeyA) + if(isKeyA) keyAList->replace(sector, key); else keyBList->replace(sector, key); diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 19ce5c0..740916a 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -1,8 +1,8 @@ #include "mainwindow.h" #include "ui_mainwindow.h" -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) +MainWindow::MainWindow(QWidget *parent): + QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); From afe2474fe369df01847fbf2e235b5770615d6a9c Mon Sep 17 00:00:00 2001 From: wh201906 Date: Fri, 1 May 2020 23:37:23 +0800 Subject: [PATCH 3/7] Add UI for simulate function --- Proxmark3GUI.pro | 3 + module/mifare.cpp | 23 ++- module/mifare.h | 2 + ui/mainwindow.cpp | 5 + ui/mainwindow.h | 2 + ui/mf_sim_simdialog.cpp | 52 ++++++ ui/mf_sim_simdialog.h | 28 ++++ ui/mf_sim_simdialog.ui | 360 ++++++++++++++++++++++++++++++++++++++++ 8 files changed, 467 insertions(+), 8 deletions(-) create mode 100644 ui/mf_sim_simdialog.cpp create mode 100644 ui/mf_sim_simdialog.h create mode 100644 ui/mf_sim_simdialog.ui diff --git a/Proxmark3GUI.pro b/Proxmark3GUI.pro index 926190c..d0aabd4 100644 --- a/Proxmark3GUI.pro +++ b/Proxmark3GUI.pro @@ -20,6 +20,7 @@ SOURCES += \ common/pm3process.cpp \ common/util.cpp \ module/mifare.cpp \ + ui/mf_sim_simdialog.cpp \ ui/mf_uid_parameterdialog.cpp \ ui/mainwindow.cpp \ ui/mf_attack_hardnesteddialog.cpp \ @@ -28,11 +29,13 @@ HEADERS += \ common/pm3process.h \ common/util.h \ module/mifare.h \ + ui/mf_sim_simdialog.h \ ui/mf_uid_parameterdialog.h \ ui/mainwindow.h \ ui/mf_attack_hardnesteddialog.h \ FORMS += \ + ui/mf_sim_simdialog.ui \ ui/mf_uid_parameterdialog.ui \ ui/mainwindow.ui \ ui/mf_attack_hardnesteddialog.ui diff --git a/module/mifare.cpp b/module/mifare.cpp index 0ff483e..fe0d56d 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -445,6 +445,18 @@ void Mifare::writeAllC() } } +void Mifare::dump() +{ + util->execCMD("hf mf dump"); + ui->funcTab->setCurrentIndex(1); +} + +void Mifare::restore() +{ + util->execCMD("hf mf restore"); + ui->funcTab->setCurrentIndex(1); +} + void Mifare::wipeC() { util->execCMD( @@ -550,17 +562,12 @@ void Mifare::wipeE() util->execCMD("hf mf eclr"); } -void Mifare::dump() +void Mifare::simulate() { - util->execCMD("hf mf dump"); - ui->funcTab->setCurrentIndex(1); + MF_Sim_simDialog dialog; + dialog.exec(); } -void Mifare::restore() -{ - util->execCMD("hf mf restore"); - ui->funcTab->setCurrentIndex(1); -} void Mifare::data_syncWithDataWidget(bool syncAll, int block) { diff --git a/module/mifare.h b/module/mifare.h index 1c0926c..72c2c87 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -5,6 +5,7 @@ #include "ui_mainwindow.h" #include "ui/mf_attack_hardnesteddialog.h" #include "ui/mf_uid_parameterdialog.h" +#include "ui/mf_sim_simdialog.h" #include #include #include @@ -108,6 +109,7 @@ public: void writeAllE(); void readAllE(); void wipeE(); + void simulate(); public slots: signals: diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 740916a..21ec486 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -673,3 +673,8 @@ void MainWindow::setState(bool st) // *********************************************** + +void MainWindow::on_MF_Sim_simButton_clicked() +{ + mifare->simulate(); +} diff --git a/ui/mainwindow.h b/ui/mainwindow.h index 5ecf277..cc3928b 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -126,6 +126,8 @@ private slots: void on_MF_Sim_clearButton_clicked(); + void on_MF_Sim_simButton_clicked(); + private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; diff --git a/ui/mf_sim_simdialog.cpp b/ui/mf_sim_simdialog.cpp new file mode 100644 index 0000000..356239b --- /dev/null +++ b/ui/mf_sim_simdialog.cpp @@ -0,0 +1,52 @@ +#include "mf_sim_simdialog.h" +#include "ui_mf_sim_simdialog.h" + +MF_Sim_simDialog::MF_Sim_simDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::MF_Sim_simDialog) +{ + ui->setupUi(this); +} + +MF_Sim_simDialog::~MF_Sim_simDialog() +{ + delete ui; +} + +void MF_Sim_simDialog::on_eBox_clicked(bool checked) +{ + if(checked) + { + ui->iBox->setChecked(true); + ui->xBox->setChecked(true); + } + if(!ui->eBox->isChecked() && !ui->fBox->isChecked()) + { + ui->iBox->setEnabled(true); + ui->xBox->setEnabled(true); + } + else + { + ui->iBox->setEnabled(false); + ui->xBox->setEnabled(false); + } +} + +void MF_Sim_simDialog::on_fBox_clicked(bool checked) +{ + if(checked) + { + ui->iBox->setChecked(true); + ui->xBox->setChecked(true); + } + if(!ui->eBox->isChecked() && !ui->fBox->isChecked()) + { + ui->iBox->setEnabled(true); + ui->xBox->setEnabled(true); + } + else + { + ui->iBox->setEnabled(false); + ui->xBox->setEnabled(false); + } +} diff --git a/ui/mf_sim_simdialog.h b/ui/mf_sim_simdialog.h new file mode 100644 index 0000000..84be8d2 --- /dev/null +++ b/ui/mf_sim_simdialog.h @@ -0,0 +1,28 @@ +#ifndef MF_SIM_SIMDIALOG_H +#define MF_SIM_SIMDIALOG_H + +#include + +namespace Ui +{ +class MF_Sim_simDialog; +} + +class MF_Sim_simDialog : public QDialog +{ + Q_OBJECT + +public: + explicit MF_Sim_simDialog(QWidget *parent = nullptr); + ~MF_Sim_simDialog(); + +private slots: + void on_eBox_clicked(bool checked); + + void on_fBox_clicked(bool checked); + +private: + Ui::MF_Sim_simDialog *ui; +}; + +#endif // MF_SIM_SIMDIALOG_H diff --git a/ui/mf_sim_simdialog.ui b/ui/mf_sim_simdialog.ui new file mode 100644 index 0000000..d66bcc0 --- /dev/null +++ b/ui/mf_sim_simdialog.ui @@ -0,0 +1,360 @@ + + + MF_Sim_simDialog + + + + 0 + 0 + 461 + 351 + + + + Dialog + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + + + u + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used + + + true + + + + + + + + + Qt::Horizontal + + + + + + + + + n + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite + + + true + + + + + + + + + Qt::Horizontal + + + + + + + + + i + + + + + + + + 0 + 0 + + + + Interactive, means that console will not be returned until simulation finishes or is aborted + + + true + + + + + + + + + Qt::Horizontal + + + + + + + + + x + + + + + + + + 0 + 0 + + + + Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s) + + + true + + + + + + + + + Qt::Horizontal + + + + + + + + + e + + + + + + + + 0 + 0 + + + + set keys found from 'reader attack' to emulator memory (implies x and i) + + + true + + + + + + + + + Qt::Horizontal + + + + + + + + + f + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i) + + + true + + + + + + + + + Qt::Horizontal + + + + + + + + + r + + + + + + + + 0 + 0 + + + + Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works. + + + true + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + MF_Sim_simDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + MF_Sim_simDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From fe8b9d6161b1786b8a7ce17f75b814fc6c20c576 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sun, 3 May 2020 00:14:49 +0800 Subject: [PATCH 4/7] Complete Mifare Simulate function --- module/mifare.cpp | 6 ++++-- ui/mf_sim_simdialog.cpp | 16 +++++++++++++++- ui/mf_sim_simdialog.h | 8 +++++++- ui/mf_sim_simdialog.ui | 20 +++++++++++++++++++- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/module/mifare.cpp b/module/mifare.cpp index fe0d56d..1817ad3 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -564,8 +564,10 @@ void Mifare::wipeE() void Mifare::simulate() { - MF_Sim_simDialog dialog; - dialog.exec(); + MF_Sim_simDialog dialog(cardType.type); + connect(&dialog, &MF_Sim_simDialog::sendCMD, util, &Util::execCMD); + if(dialog.exec() == QDialog::Accepted) + ui->funcTab->setCurrentIndex(1); } diff --git a/ui/mf_sim_simdialog.cpp b/ui/mf_sim_simdialog.cpp index 356239b..c0ba180 100644 --- a/ui/mf_sim_simdialog.cpp +++ b/ui/mf_sim_simdialog.cpp @@ -1,11 +1,12 @@ #include "mf_sim_simdialog.h" #include "ui_mf_sim_simdialog.h" -MF_Sim_simDialog::MF_Sim_simDialog(QWidget *parent) : +MF_Sim_simDialog::MF_Sim_simDialog(int cardType, QWidget *parent) : QDialog(parent), ui(new Ui::MF_Sim_simDialog) { ui->setupUi(this); + this->cardType = cardType; } MF_Sim_simDialog::~MF_Sim_simDialog() @@ -50,3 +51,16 @@ void MF_Sim_simDialog::on_fBox_clicked(bool checked) ui->xBox->setEnabled(false); } } + +void MF_Sim_simDialog::on_buttonBox_accepted() +{ + QString paras; + paras += (ui->uBox->isChecked() ? "u " + ui->uEdit->text() + " " : ""); + paras += (ui->nBox->isChecked() ? "n " + ui->nEdit->text() + " " : ""); + paras += (ui->iBox->isChecked() ? "i " : ""); + paras += (ui->xBox->isChecked() ? "x " : ""); + paras += (ui->eBox->isChecked() ? "e " : ""); + paras += (ui->fBox->isChecked() ? "f " + ui->fEdit->text() + " " : ""); + paras += (ui->rBox->isChecked() ? "r " : ""); + emit sendCMD(QString("hf mf sim ") + "*" + QString::number(cardType) + " " + paras.trimmed()); +} diff --git a/ui/mf_sim_simdialog.h b/ui/mf_sim_simdialog.h index 84be8d2..7fa53a1 100644 --- a/ui/mf_sim_simdialog.h +++ b/ui/mf_sim_simdialog.h @@ -2,6 +2,7 @@ #define MF_SIM_SIMDIALOG_H #include +#include namespace Ui { @@ -13,7 +14,7 @@ class MF_Sim_simDialog : public QDialog Q_OBJECT public: - explicit MF_Sim_simDialog(QWidget *parent = nullptr); + explicit MF_Sim_simDialog(int cardType, QWidget *parent = nullptr); ~MF_Sim_simDialog(); private slots: @@ -23,6 +24,11 @@ private slots: private: Ui::MF_Sim_simDialog *ui; + int cardType; +signals: + void sendCMD(QString cmd); +private slots: + void on_buttonBox_accepted(); }; #endif // MF_SIM_SIMDIALOG_H diff --git a/ui/mf_sim_simdialog.ui b/ui/mf_sim_simdialog.ui index d66bcc0..97b4edf 100644 --- a/ui/mf_sim_simdialog.ui +++ b/ui/mf_sim_simdialog.ui @@ -7,7 +7,7 @@ 0 0 461 - 351 + 456 @@ -46,6 +46,12 @@ 0 + + + 100 + 16777215 + + @@ -90,6 +96,12 @@ 0 + + + 100 + 16777215 + + @@ -236,6 +248,12 @@ 0 + + + 100 + 16777215 + + From 5816d1b1b64a76804e3487eaa0aa36fe85d301b2 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sun, 3 May 2020 23:40:09 +0800 Subject: [PATCH 5/7] Complete Mifare module --- module/mifare.cpp | 11 +++++++++++ module/mifare.h | 2 ++ ui/mainwindow.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++- ui/mainwindow.h | 4 ++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/module/mifare.cpp b/module/mifare.cpp index 1817ad3..912e599 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -570,6 +570,17 @@ void Mifare::simulate() ui->funcTab->setCurrentIndex(1); } +void Mifare::loadSniff(const QString& file) +{ + util->execCMD("hf list mf -l " + file); + ui->funcTab->setCurrentIndex(1); +} + +void Mifare::saveSniff(const QString& file) +{ + util->execCMD("hf list mf -s " + file); + ui->funcTab->setCurrentIndex(1); +} void Mifare::data_syncWithDataWidget(bool syncAll, int block) { diff --git a/module/mifare.h b/module/mifare.h index 72c2c87..4d804b6 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -110,6 +110,8 @@ public: void readAllE(); void wipeE(); void simulate(); + void loadSniff(const QString& file); + void saveSniff(const QString& file); public slots: signals: diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 21ec486..a396480 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -7,7 +7,7 @@ MainWindow::MainWindow(QWidget *parent): { ui->setupUi(this); // ui->MF_simGroupBox->setVisible(false); // developing... - ui->MF_sniffGroupBox->setVisible(false); // developing... +// ui->MF_sniffGroupBox->setVisible(false); // developing... myInfo = new QAction("wh201906", this); connect(myInfo, &QAction::triggered, [ = ]() { @@ -678,3 +678,46 @@ void MainWindow::on_MF_Sim_simButton_clicked() { mifare->simulate(); } + +void MainWindow::on_MF_Sniff_loadButton_clicked() // use a tmp file to support complicated path +{ + QString title = ""; + QString filename = ""; + + title = tr("Plz select the trace file:"); + filename = QFileDialog::getOpenFileName(this, title, "./", tr("Trace Files(*.trc);;All Files(*.*)")); + qDebug() << filename; + if(filename != "") + { + QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc"; + if(QFile::copy(filename, "./" + tmpFile)) + { + mifare->loadSniff(tmpFile); + QFile::remove("./" + tmpFile); + } + else + { + QMessageBox::information(this, tr("Info"), tr("Failed to open") + "\n" + filename); + } + } +} + +void MainWindow::on_MF_Sniff_saveButton_clicked() +{ + QString title = ""; + QString filename = ""; + + title = tr("Plz select the location to save trace file:"); + filename = QFileDialog::getSaveFileName(this, title, "./", tr("Trace Files(*.trc)")); + qDebug() << filename; + if(filename != "") + { + QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc"; + mifare->saveSniff(tmpFile); + if(!QFile::copy("./" + tmpFile, filename)) + { + QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename); + } + } + +} diff --git a/ui/mainwindow.h b/ui/mainwindow.h index cc3928b..087fc5d 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -128,6 +128,10 @@ private slots: void on_MF_Sim_simButton_clicked(); + void on_MF_Sniff_loadButton_clicked(); + + void on_MF_Sniff_saveButton_clicked(); + private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; From 2790afc193714dd0cf9675286f9006c2866716b2 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sat, 9 May 2020 23:43:10 +0800 Subject: [PATCH 6/7] Support Mifare Simulate and Sniff function --- lang/en_US.ts | 267 +++++++++++++++++++++++++++------------ lang/zh_CN.ts | 275 +++++++++++++++++++++++++++++------------ ui/mainwindow.cpp | 96 +++++++------- ui/mainwindow.ui | 7 ++ ui/mf_sim_simdialog.ui | 4 +- 5 files changed, 440 insertions(+), 209 deletions(-) diff --git a/lang/en_US.ts b/lang/en_US.ts index 729872e..1cb5ab4 100644 --- a/lang/en_US.ts +++ b/lang/en_US.ts @@ -37,6 +37,84 @@ + + MF_Sim_simDialog + + + Simulate + + + + + u + + + + + UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used + + + + + n + + + + + Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite + + + + + i + + + + + Interactive, means that console will not be returned until simulation finishes or is aborted + + + + + x + + + + + Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s) + + + + + e + + + + + set keys found from 'reader attack' to emulator memory (implies x and i) + + + + + f + + + + + get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i) + + + + + r + + + + + Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works + + + MF_UID_parameterDialog @@ -88,250 +166,255 @@ - + Mifare - + >> - + << - + F - + Card Type - + MINI - + 1K - + 2K - + 4K - + File - - + + Load - - + + Save - - + + Data - + Key - + Attack - + Card Info - + Check Default - + Nested - + Hardnested - + Read/Write - + Block: - + Key: - + Key Type: - + A - + B - + + Data: + + + + Normal(Require Password) - - + + Read Block - - + + Write Block - - - + + + Read All - - + + Write All - + Dump - + Restore - + Chinese Magic Card(Without Password) - + Lock UFUID Card - + About UID Card - + Set Parameter - + Wipe - - + + Simulate - + Load from data above - - + + Clear - - + + Sniff - + List Sniff Data - + RawCommand - + History: - + ClearHistory - + Send - + ClearOutput @@ -345,6 +428,8 @@ + + Info @@ -361,7 +446,7 @@ - + Not Connected @@ -373,6 +458,7 @@ + Failed to open @@ -430,6 +516,7 @@ + Failed to save to @@ -529,49 +616,69 @@ - - + + Plz select the trace file: + + + + + Trace Files(*.trc);;All Files(*.*) + + + + + Plz select the location to save trace file: + + + + + Trace Files(*.trc) + + + + + Idle - - + + Sec - + Blk - + KeyA - + KeyB - + HW Version: - + PM3: - + State: - + Running @@ -579,28 +686,28 @@ Mifare - - + + Success! - - - - - + + + + + Info - - + + Failed! - + Failed to read card. diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts index 921ff20..3ae33f8 100644 --- a/lang/zh_CN.ts +++ b/lang/zh_CN.ts @@ -45,6 +45,92 @@ 目标块: + + MF_Sim_simDialog + + Dialog + 对话框 + + + + Simulate + 模拟 + + + + u + + + + + UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used + 4或7字节的UID,如果不指定,则使用模拟器内存中的4字节UID + + + + n + + + + + Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite + 在读卡器读取<n>个块后自动退出模拟,n为0或不指定时永远不退出 + + + + i + + + + + Interactive, means that console will not be returned until simulation finishes or is aborted + 交互模式,勾选后PM3客户端将在模拟完成或者模拟中断后才可继续使用 + + + + x + + + + + Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s) + 破解,对读卡器进行攻击,通过nr/ar攻击来钓出密码(无卡嗅探) + + + + e + + + + + set keys found from 'reader attack' to emulator memory (implies x and i) + 在获得密码后自动将密码写入模拟器内存(自动勾选x和i) + + + + f + + + + + get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i) + 从<filename.txt>当中获取用于破解读卡器的UID(批量模拟)(自动勾选x和i) + + + + r + + + + + Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works + 生成随机nonce而不是顺序的nonce,这种情况下PM3将不对读卡器进行标准攻击,只进行moebius攻击 + + + Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works. + 生成随机nonce而不是顺序的nonce,这种情况下PM3将不对读卡器进行标准攻击,只进行moebius攻击 + + MF_UID_parameterDialog @@ -104,250 +190,255 @@ 断开 - + Mifare Mifare(IC)卡 - + >> - + << - + F - + Card Type 卡类型 - + MINI - + 1K - + 2K - + 4K - + File 文件 - - + + Load 加载 - - + + Save 保存 - - + + Data - + Key - + Attack 破解 - + Card Info 读卡片信息 - + Check Default 验证默认密码 - + Nested Nested攻击 - + Hardnested Hardested攻击 - + Read/Write 读/写 - + Block: - + Key: - + Key Type: Key类型: - + A - + B - + + Data: + + + + Normal(Require Password) 普通卡(需要密码) - - + + Read Block 读单个块 - - + + Write Block 写单个块 - - - + + + Read All 读所有块 - - + + Write All 写所有块 - + Dump Dump命令 - + Restore Restore命令 - + Chinese Magic Card(Without Password) UID卡(不需要密码) - + Lock UFUID Card 锁定UFUID卡 - + About UID Card 关于UID卡 - + Set Parameter 设置卡参数 - + Wipe 擦除 - - + + Simulate 模拟 - + Load from data above 从上方数据导入 - - + + Clear 清空 - - + + Sniff 嗅探 - + List Sniff Data 列出嗅探数据 - + RawCommand 原始命令 - + History: 命令历史: - + ClearHistory 清空历史 - + Send 发送 - + ClearOutput 清空输出 @@ -361,6 +452,8 @@ + + Info 信息 @@ -377,7 +470,7 @@ - + Not Connected 未连接 @@ -398,6 +491,7 @@ Continue? + Failed to open 无法打开 @@ -467,6 +561,7 @@ Continue? + Failed to save to 无法保存至 @@ -566,49 +661,69 @@ Continue? 所有UID卡都似乎更容易被Nested攻击破解 - - + + Plz select the trace file: + 请选择trace文件: + + + + Trace Files(*.trc);;All Files(*.*) + Trace文件(*.trc);;所有文件(*.*) + + + + Plz select the location to save trace file: + 请选择trace文件保存的位置: + + + + Trace Files(*.trc) + Trace文件(*.trc) + + + + Idle 空闲 - - + + Sec - + Blk - + KeyA - + KeyB - + HW Version: 固件版本: - + PM3: 连接状态: - + State: 运行状态: - + Running 运行中 @@ -620,28 +735,28 @@ Continue? 信息: - - + + Success! 成功! - - - - - + + + + + Info 信息 - - + + Failed! 失败! - + Failed to read card. 读卡失败。 diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index a396480..7259805 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -50,7 +50,6 @@ void MainWindow::initUI() // will be called by main.app void MainWindow::on_PM3_refreshPortButton_clicked() { ui->PM3_portBox->clear(); - ui->PM3_portBox->addItem(""); QSerialPort serial; QStringList serialList; foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) @@ -493,6 +492,55 @@ void MainWindow::on_MF_Sim_clearButton_clicked() mifare->wipeE(); } +void MainWindow::on_MF_Sim_simButton_clicked() +{ + mifare->simulate(); +} + +void MainWindow::on_MF_Sniff_loadButton_clicked() // use a tmp file to support complicated path +{ + QString title = ""; + QString filename = ""; + + title = tr("Plz select the trace file:"); + filename = QFileDialog::getOpenFileName(this, title, "./", tr("Trace Files(*.trc);;All Files(*.*)")); + qDebug() << filename; + if(filename != "") + { + QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc"; + if(QFile::copy(filename, "./" + tmpFile)) + { + mifare->loadSniff(tmpFile); + QFile::remove("./" + tmpFile); + } + else + { + QMessageBox::information(this, tr("Info"), tr("Failed to open") + "\n" + filename); + } + } +} + +void MainWindow::on_MF_Sniff_saveButton_clicked() +{ + QString title = ""; + QString filename = ""; + + title = tr("Plz select the location to save trace file:"); + filename = QFileDialog::getSaveFileName(this, title, "./", tr("Trace Files(*.trc)")); + qDebug() << filename; + if(filename != "") + { + QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc"; + mifare->saveSniff(tmpFile); + if(!QFile::copy("./" + tmpFile, filename)) + { + QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename); + } + QFile::remove("./" + tmpFile); + } + +} + void MainWindow::on_MF_Sniff_sniffButton_clicked() { setState(false); @@ -674,50 +722,4 @@ void MainWindow::setState(bool st) -void MainWindow::on_MF_Sim_simButton_clicked() -{ - mifare->simulate(); -} - -void MainWindow::on_MF_Sniff_loadButton_clicked() // use a tmp file to support complicated path -{ - QString title = ""; - QString filename = ""; - title = tr("Plz select the trace file:"); - filename = QFileDialog::getOpenFileName(this, title, "./", tr("Trace Files(*.trc);;All Files(*.*)")); - qDebug() << filename; - if(filename != "") - { - QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc"; - if(QFile::copy(filename, "./" + tmpFile)) - { - mifare->loadSniff(tmpFile); - QFile::remove("./" + tmpFile); - } - else - { - QMessageBox::information(this, tr("Info"), tr("Failed to open") + "\n" + filename); - } - } -} - -void MainWindow::on_MF_Sniff_saveButton_clicked() -{ - QString title = ""; - QString filename = ""; - - title = tr("Plz select the location to save trace file:"); - filename = QFileDialog::getSaveFileName(this, title, "./", tr("Trace Files(*.trc)")); - qDebug() << filename; - if(filename != "") - { - QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc"; - mifare->saveSniff(tmpFile); - if(!QFile::copy("./" + tmpFile, filename)) - { - QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename); - } - } - -} diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 94e2915..8e90e42 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -608,6 +608,13 @@ + + + + Data: + + + diff --git a/ui/mf_sim_simdialog.ui b/ui/mf_sim_simdialog.ui index 97b4edf..1a9c15a 100644 --- a/ui/mf_sim_simdialog.ui +++ b/ui/mf_sim_simdialog.ui @@ -11,7 +11,7 @@ - Dialog + Simulate @@ -299,7 +299,7 @@ - Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works. + Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works true From 461c48fee9924d59bf2e2e81b22a985dcfc47da2 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sat, 9 May 2020 23:49:25 +0800 Subject: [PATCH 7/7] V0.1.1 --- Proxmark3GUI.pro | 2 +- README.md | 3 +++ README/README.zh_CN.md | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Proxmark3GUI.pro b/Proxmark3GUI.pro index d0aabd4..b01adb0 100644 --- a/Proxmark3GUI.pro +++ b/Proxmark3GUI.pro @@ -49,7 +49,7 @@ qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target -VERSION = 0.1 +VERSION = 0.1.1 QMAKE_TARGET_PRODUCT = "Proxmark3GUI" QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI" QMAKE_TARGET_COMPANY = "wh201906" diff --git a/README.md b/README.md index 6e6477b..809caac 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,9 @@ A GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client ## Update Log: +### V0.1.1 ++ Complete Mifare module(support simulate and sniff) + ### V0.1 + Able to deal with Mifare card and related files diff --git a/README/README.zh_CN.md b/README/README.zh_CN.md index 9e18da8..fdb8734 100644 --- a/README/README.zh_CN.md +++ b/README/README.zh_CN.md @@ -28,6 +28,9 @@ ## 更新日志: +### V0.1.1 ++ 完成整个Mifare模块(支持模拟卡和嗅探功能) + ### V0.1 + 支持处理Mifare卡片及相关数据文件