diff --git a/Proxmark3GUI.pro b/Proxmark3GUI.pro index 14ca8be..c450bfa 100644 --- a/Proxmark3GUI.pro +++ b/Proxmark3GUI.pro @@ -34,6 +34,10 @@ FORMS += \ ui/mainwindow.ui \ ui/mf_attack_hardnesteddialog.ui +TRANSLATIONS += \ + lang/zh_CN.ts \ + lang/en_US.ts + # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin @@ -43,3 +47,5 @@ VERSION = 0.0.1 QMAKE_TARGET_PRODUCT = "Proxmark3GUI" QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI" QMAKE_TARGET_COMPANY = "wh201906" + +LANGUAGES diff --git a/lang/en_US.ts b/lang/en_US.ts new file mode 100644 index 0000000..b949903 --- /dev/null +++ b/lang/en_US.ts @@ -0,0 +1,382 @@ + + + + + MF_Attack_hardnestedDialog + + + Dialog + + + + + Known Key: + + + + + + Block: + + + + + + A + + + + + + B + + + + + FFFFFFFFFFFF + + + + + Target Key: + + + + + MainWindow + + + Proxmark3GUI + + + + + Path: + + + + + E:\Documents\source\qt\pm3\win64\proxmark3 + + + + + Refresh + + + + + Connect + + + + + Disconnect + + + + + Mifare + + + + + >> + + + + + << + + + + + Card Type + + + + + 1K + + + + + 2K + + + + + 4K + + + + + File + + + + + + Load + + + + + + Save + + + + + + Data + + + + + Key + + + + + Attack + + + + + Card Info + + + + + Check Default + + + + + Nested + + + + + Hardnested + + + + + Read/Write + + + + + Block: + + + + + Key: + + + + + FFFFFFFFFFFF + + + + + Key Type: + + + + + A + + + + + B + + + + + Normal(Require Password) + + + + + + Read Block + + + + + + Write Block + + + + + + + Read All + + + + + + Write All + + + + + Dump + + + + + Restore + + + + + Chinese Magic Card(Without Password) + + + + + Lock UFUID Card + + + + + About UID Card + + + + + Write UID + + + + + Wipe + + + + + + Simulate + + + + + Load from data above + + + + + Clear + + + + + + Sniff + + + + + List Sniff Data + + + + + RawCommand + + + + + + History: + + + + + ClearHistory + + + + + Send + + + + + ClearOutput + + + + + Info + + + + + Plz choose a port first + + + + + Connected + + + + + + + Not Connected + + + + + Idle + + + + + + Sec + + + + + Blk + + + + + KeyA + + + + + KeyB + + + + + HW Version: + + + + + PM3: + + + + + State: + + + + diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts new file mode 100644 index 0000000..b949903 --- /dev/null +++ b/lang/zh_CN.ts @@ -0,0 +1,382 @@ + + + + + MF_Attack_hardnestedDialog + + + Dialog + + + + + Known Key: + + + + + + Block: + + + + + + A + + + + + + B + + + + + FFFFFFFFFFFF + + + + + Target Key: + + + + + MainWindow + + + Proxmark3GUI + + + + + Path: + + + + + E:\Documents\source\qt\pm3\win64\proxmark3 + + + + + Refresh + + + + + Connect + + + + + Disconnect + + + + + Mifare + + + + + >> + + + + + << + + + + + Card Type + + + + + 1K + + + + + 2K + + + + + 4K + + + + + File + + + + + + Load + + + + + + Save + + + + + + Data + + + + + Key + + + + + Attack + + + + + Card Info + + + + + Check Default + + + + + Nested + + + + + Hardnested + + + + + Read/Write + + + + + Block: + + + + + Key: + + + + + FFFFFFFFFFFF + + + + + Key Type: + + + + + A + + + + + B + + + + + Normal(Require Password) + + + + + + Read Block + + + + + + Write Block + + + + + + + Read All + + + + + + Write All + + + + + Dump + + + + + Restore + + + + + Chinese Magic Card(Without Password) + + + + + Lock UFUID Card + + + + + About UID Card + + + + + Write UID + + + + + Wipe + + + + + + Simulate + + + + + Load from data above + + + + + Clear + + + + + + Sniff + + + + + List Sniff Data + + + + + RawCommand + + + + + + History: + + + + + ClearHistory + + + + + Send + + + + + ClearOutput + + + + + Info + + + + + Plz choose a port first + + + + + Connected + + + + + + + Not Connected + + + + + Idle + + + + + + Sec + + + + + Blk + + + + + KeyA + + + + + KeyB + + + + + HW Version: + + + + + PM3: + + + + + State: + + + + diff --git a/module/mifare.cpp b/module/mifare.cpp index c034c0d..77c3453 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -4,12 +4,15 @@ Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QObject *parent) : QObject(parent { util = addr; this->ui = ui; + cardType = card_1k; keyAList = new QStringList(); keyBList = new QStringList(); dataList = new QStringList(); 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}\\|.+\\|.+\\|.+\\|.+\\|"); } @@ -22,36 +25,43 @@ void Mifare::info() void Mifare::chk() { - QString result = util->execCMDWithOutput("hf mf chk *1 ?"); - result = result.mid(result.indexOf("|---|----------------|----------------|")); - QStringList keys = result.split("\r\n"); - for(int i = 0; i < 16; i++) + QString result = util->execCMDWithOutput("hf mf chk *" + QString::number(cardType.type) + " ?"); + + int offset = 0; + QString tmp, tmp2; + for(int i = 0; i < cardType.sectors; i++) { - keyAList->replace(i, keys[i + 3].mid(7, 12).trimmed().toUpper()); - if(keyAList->at(i) == "?") - keyAList->replace(i, ""); - keyBList->replace(i, keys[i + 3].mid(24, 12).trimmed().toUpper()); - if(keyBList->at(i) == "?") - keyBList->replace(i, ""); + offset = result.indexOf(*chkKeyPattern, offset); + tmp = result.mid(offset, 39).toUpper(); + offset += 39; + qDebug() << tmp << offset; + tmp2 = tmp.mid(7, 12).trimmed(); + if(tmp2 != "?") + keyAList->replace(i, tmp2); + tmp2 = tmp.mid(24, 12).trimmed(); + if(tmp2 != "?") + keyBList->replace(i, tmp2); } data_syncWithKeyWidget(); - qDebug() << "***********\n" << keys << "***********\n"; } void Mifare::nested() { - QString result = util->execCMDWithOutput("hf mf nested 1 *"); - result = result.mid(result.indexOf("|---|----------------|---|----------------|---|")); - QStringList keys = result.split("\r\n"); - for(int i = 0; i < 16; i++) + QString result = util->execCMDWithOutput("hf mf nested " + QString::number(cardType.type) + " *"); + + int offset = 0; + QString tmp; + for(int i = 0; i < cardType.sectors; i++) { - if(keys[i + 3].at(23) == '1') - keyAList->replace(i, keys[i + 3].mid(7, 12).trimmed().toUpper()); - if(keys[i + 3].at(44) == '1') - keyBList->replace(i, keys[i + 3].mid(28, 12).trimmed().toUpper()); + offset = result.indexOf(*nestedKeyPattern, offset); + tmp = result.mid(offset, 47).toUpper(); + offset += 47; + if(tmp.at(23) == '1') + keyAList->replace(i, tmp.mid(7, 12).trimmed()); + if(tmp.at(44) == '1') + keyBList->replace(i, tmp.mid(28, 12).trimmed()); } data_syncWithKeyWidget(); - qDebug() << "***********\n" << keys << "***********\n"; } void Mifare::hardnested() @@ -126,12 +136,13 @@ void Mifare::read() void Mifare::readAll() { QString result; - QString tmp; - int offset = 0; bool isKeyAValid; bool isKeyBValid; const int waitTime = 150; - for(int i = 0; i < sectors; i++) + + QString tmp; + int offset = 0; + for(int i = 0; i < cardType.sectors; i++) { result = ""; isKeyAValid = false; @@ -149,9 +160,10 @@ void Mifare::readAll() if(offset != -1) { isKeyAValid = true; - for(int j = 0; j < 4; j++) + for(int j = 0; j < cardType.blk[i]; j++) { - tmp = result.mid(result.indexOf(*dataPattern, offset), 47).toUpper(); + offset = result.indexOf(*dataPattern, offset); + tmp = result.mid(offset, 47).toUpper(); offset += 47; qDebug() << tmp; tmp.replace(" ", ""); @@ -173,7 +185,8 @@ void Mifare::readAll() isKeyBValid = true; for(int j = 0; j < 4; j++) { - tmp = result.mid(result.indexOf(*dataPattern, offset), 47).toUpper(); + offset = result.indexOf(*dataPattern, offset); + tmp = result.mid(offset, 47).toUpper(); offset += 47; qDebug() << tmp; tmp.replace(" ", ""); @@ -301,7 +314,7 @@ void Mifare::data_syncWithDataWidget(bool syncAll, int block) QString tmp = ""; if(syncAll) { - for(int i = 0; i < blocks; i++) + for(int i = 0; i < cardType.blk[block]; i++) { tmp += dataList->at(i).mid(0, 2); for(int j = 1; j < 16; j++) @@ -328,7 +341,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) { if(syncAll) { - for(int i = 0; i < 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)); @@ -346,7 +359,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA) void Mifare::data_clearData() { dataList->clear(); - for(int i = 0; i < blocks; i++) + for(int i = 0; i < 40; i++) dataList->append(""); } @@ -354,7 +367,7 @@ void Mifare::data_clearKey() { keyAList->clear(); keyBList->clear(); - for(int i = 0; i < sectors; i++) + for(int i = 0; i < cardType.sectors; i++) { keyAList->append(""); keyBList->append(""); diff --git a/module/mifare.h b/module/mifare.h index 8709463..b4df46a 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -34,6 +34,43 @@ public: DATA_NOSPACE, }; + struct CardType + { + int type; + int sectors; + int blk[40]; + int blks[40]; + }; + + const CardType card_mini = + { + 0, + 5, + {4, 4, 4, 4, 4}, + {0, 4, 8, 12, 16} + }; + const CardType card_1k = + { + 1, + 16, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60} + }; + const CardType card_2k = + { + 2, + 32, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, + {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124} + }; + const CardType card_4k = + { + 4, + 40, + {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 16}, + {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 144, 160, 176, 192, 208, 224, 240} + }; + void data_clearData(); void data_clearKey(); bool data_isKeyValid(const QString &key); @@ -51,9 +88,10 @@ private: QStringList* keyBList; QStringList* dataList; QRegExp* dataPattern; + QRegExp* chkKeyPattern; + QRegExp* nestedKeyPattern; - int sectors = 16; - int blocks = 64; + CardType cardType; }; #endif // MIFARE_H diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 6de706e..ec08bd1 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -62,7 +62,7 @@ void MainWindow::on_PM3_connectButton_clicked() qDebug() << "Main:" << QThread::currentThread(); QString port = ui->PM3_portBox->currentText(); if(port == "") - QMessageBox::information(NULL, "Info", "Plz choose a port first", QMessageBox::Ok); + QMessageBox::information(NULL, tr("Info"), tr("Plz choose a port first"), QMessageBox::Ok); else { emit connectPM3(ui->PM3_pathEdit->text(), port); @@ -75,11 +75,11 @@ void MainWindow::onPM3StateChanged(bool st, QString info) if(st == true) { setStatusBar(PM3VersionBar, info); - setStatusBar(connectStatusBar, "Connected"); + setStatusBar(connectStatusBar, tr("Connected")); } else { - setStatusBar(connectStatusBar, "Not Connected"); + setStatusBar(connectStatusBar, tr("Not Connected")); } } @@ -88,7 +88,7 @@ void MainWindow::on_PM3_disconnectButton_clicked() pm3state = false; emit killPM3(); emit setSerialListener("", false); - setStatusBar(connectStatusBar, "Not Connected"); + setStatusBar(connectStatusBar, tr("Not Connected")); } void MainWindow::refreshOutput(const QString& output) @@ -126,7 +126,7 @@ void MainWindow::on_Raw_CMDHistoryBox_stateChanged(int arg1) { ui->Raw_CMDHistoryWidget->setVisible(true); ui->Raw_clearHistoryButton->setVisible(true); - ui->Raw_CMDHistoryBox->setText("History:"); + ui->Raw_CMDHistoryBox->setText(tr("History:")); } else { @@ -229,8 +229,8 @@ void MainWindow::uiInit() connectStatusBar = new QLabel(this); programStatusBar = new QLabel(this); PM3VersionBar = new QLabel(this); - setStatusBar(connectStatusBar, "Not Connected"); - setStatusBar(programStatusBar, "Idle"); + setStatusBar(connectStatusBar, tr("Not Connected")); + setStatusBar(programStatusBar, tr("Idle")); setStatusBar(PM3VersionBar, ""); ui->statusbar->addPermanentWidget(PM3VersionBar, 1); ui->statusbar->addPermanentWidget(connectStatusBar, 1); @@ -238,9 +238,9 @@ void MainWindow::uiInit() ui->MF_dataWidget->setColumnCount(3); ui->MF_dataWidget->setRowCount(64); - ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("Sec")); - ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("Blk")); - ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("Data")); + ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec"))); + ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Blk"))); + ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Data"))); for(int i = 0; i < 64; i++) { ui->MF_dataWidget->setItem(i, 1, new QTableWidgetItem(QString::number(i))); @@ -255,9 +255,9 @@ void MainWindow::uiInit() ui->MF_keyWidget->setColumnCount(3); ui->MF_keyWidget->setRowCount(16); - ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("Sec")); - ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem("KeyA")); - ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem("KeyB")); + ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec"))); + ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("KeyA"))); + ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB"))); for(int i = 0; i < 16; i++) { ui->MF_keyWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i))); @@ -293,11 +293,11 @@ void MainWindow::signalInit() void MainWindow::setStatusBar(QLabel* target, const QString & text) { if(target == PM3VersionBar) - target->setText("HW Version:" + text); + target->setText(tr("HW Version:") + text); else if(target == connectStatusBar) - target->setText("PM3:" + text); + target->setText(tr("PM3:") + text); else if(target == programStatusBar) - target->setText("State:" + text); + target->setText(tr("State:") + text); } // *********************************************** diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 05fca61..bca0f3f 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -113,6 +113,9 @@ Courier + + QAbstractItemView::SingleSelection + 20 @@ -449,6 +452,12 @@ true + + 0 + + + -1 +