From a3e6aa787b6c3b019bf492961246b8fa2e1bb1da Mon Sep 17 00:00:00 2001 From: wh201906 Date: Tue, 11 Aug 2020 11:30:33 +0800 Subject: [PATCH 1/7] Check Access Bits when writing to selected blocks --- README.md | 2 +- module/mifare.cpp | 55 +++++++++++++++++++++++++++++++++++++++-------- module/mifare.h | 1 + 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 228b2de..0b104e3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ A GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client ## Preview ![preview](README/img/preview.png) -more previews [here](README/doc/previews.md) +[more previews](README/doc/previews.md) *** diff --git a/module/mifare.cpp b/module/mifare.cpp index 5c0f63e..a82816b 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -273,7 +273,7 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, Targe { QString data; QString result; - bool isKeyBlock = (blockId < 128 && ((blockId + 1) % 4 == 0)) || ((blockId + 1) % 16 == 0); + bool isTrailerBlock = (blockId < 128 && ((blockId + 1) % 4 == 0)) || ((blockId + 1) % 16 == 0); if(util->getClientType() == Util::CLIENTTYPE_OFFICIAL || util->getClientType() == Util::CLIENTTYPE_ICEMAN) { @@ -298,7 +298,7 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, Targe data.remove(" "); // when the target block is a key block and the given key type is KeyA, try to check whether the KeyB is valid(by Access Bits) // if the given key type is KeyB, it will never get the KeyA from the key block - if(isKeyBlock && keyType == KEY_A) // in this case, the Access Bits is always accessible + if(isTrailerBlock && keyType == KEY_A) // in this case, the Access Bits is always accessible { data.replace(0, 12, key); QList ACBits = data_getACBits(data.mid(12, 8)); @@ -307,7 +307,7 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, Targe data.replace(20, 12, "????????????"); } } - else if(isKeyBlock && keyType == KEY_B) + else if(isTrailerBlock && keyType == KEY_B) { data.replace(20, 12, key);; data.replace(0, 12, "????????????"); // fill the keyA part with ? @@ -536,8 +536,8 @@ bool Mifare::_writeblk(int blockId, KeyType keyType, const QString& key, const Q { QString result; QString input = data.toUpper(); - input.remove(" "); + input.remove(" "); if(data_isDataValid(input) != DATA_NOSPACE) return false; @@ -601,6 +601,8 @@ void Mifare::writeSelected(TargetType targetType) { QList failedBlocks; QList selectedBlocks; + bool yes2All = false, no2All = false; + for(int i = 0; i < cardType.block_size; i++) { if(ui->MF_dataWidget->item(i, 1)->checkState() == Qt::Checked) @@ -609,6 +611,29 @@ void Mifare::writeSelected(TargetType targetType) for(int item : selectedBlocks) { bool result = false; + bool isTrailerBlock = (item < 128 && ((item + 1) % 4 == 0)) || ((item + 1) % 16 == 0); + + if(isTrailerBlock && !data_isACBitsValid(dataList->at(item).mid(12, 8))) // trailer block is invalid + { + if(!yes2All && !no2All) + { + QMessageBox::StandardButton choice = QMessageBox::information(parent, tr("Info"), + tr("The Access Bits is invalid!\nIt could make the whole sector blocked irreversibly!\nContinue to write?"), + QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll); + if(choice == QMessageBox::No) + continue; + else if(choice == QMessageBox::YesToAll) + yes2All = true; + else if(QMessageBox::NoToAll) + { + no2All = true; + continue; + } + } + else if(no2All) + continue; + } + if(targetType == TARGET_MIFARE) { result = _writeblk(item, KEY_A, keyAList->at(data_b2s(item)), dataList->at(item), TARGET_MIFARE); @@ -1192,24 +1217,36 @@ int Mifare::data_b2s(int block) return -1; } -QList Mifare::data_getACBits(const QString& text) //return empty QList if the text is invalid +bool Mifare::data_isACBitsValid(const QString& text, QList* returnHalfBytes) { QString input = text; - QList result; input.remove(" "); if(input.length() < 6) { - return result; + return false; } input = input.left(6); quint32 val = input.toUInt(nullptr, 16); - quint8 halfBytes[6]; + QList halfBytes; for(int i = 0; i < 6; i++) { - halfBytes[i] = (val >> ((5 - i) * 4)) & 0xf; + halfBytes.append((val >> ((5 - i) * 4)) & 0xf); } qDebug() << val; if((~halfBytes[0] & 0xf) == halfBytes[5] && (~halfBytes[1] & 0xf) == halfBytes[2] && (~halfBytes[3] & 0xf) == halfBytes[4]) + { + if(returnHalfBytes != nullptr) + *returnHalfBytes = halfBytes; + return true; + } + else + return false; +} + +QList Mifare::data_getACBits(const QString& text) //return empty QList if the text is invalid +{ + QList halfBytes, result; + if(data_isACBitsValid(text, &halfBytes)) { for(int i = 0; i < 4; i++) { diff --git a/module/mifare.h b/module/mifare.h index 7865755..b328314 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -108,6 +108,7 @@ public: static QList data_getACBits(const QString &text); static int data_b2s(int block); + static bool data_isACBitsValid(const QString &text, QList *returnHalfBytes = nullptr); public slots: signals: From a7985c5c895b69aeb926c3991507d0498de60164 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Tue, 11 Aug 2020 11:51:27 +0800 Subject: [PATCH 2/7] Stop the running command after disconnected --- common/util.cpp | 10 +++++++++- common/util.h | 2 ++ ui/mainwindow.cpp | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/common/util.cpp b/common/util.cpp index 3d73cc3..707dfe7 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -23,11 +23,14 @@ void Util::processOutput(QString output) void Util::execCMD(QString cmd) { qDebug() << cmd; - emit write(cmd + "\r\n"); + if(isRunning) + emit write(cmd + "\r\n"); } QString Util::execCMDWithOutput(QString cmd, unsigned long waitTime) { + if(!isRunning) + return ""; QTime currTime = QTime::currentTime(); QTime targetTime = QTime::currentTime().addMSecs(waitTime); isRequiringOutput = true; @@ -61,3 +64,8 @@ void Util::setClientType(Util::ClientType clientType) { this->clientType = clientType; } + +void Util::setRunningState(bool st) +{ + this->isRunning = st; +} diff --git a/common/util.h b/common/util.h index adc9291..b2ca006 100644 --- a/common/util.h +++ b/common/util.h @@ -31,9 +31,11 @@ public: public slots: void processOutput(QString output); void setClientType(Util::ClientType clientType); + void setRunningState(bool st); private: bool isRequiringOutput; + bool isRunning; QString* requiredOutput; QTime timeStamp; ClientType clientType; diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 2b30c0f..8fbbd8a 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -875,6 +875,7 @@ void MainWindow::signalInit() connect(this, &MainWindow::connectPM3, pm3, &PM3Process::connectPM3); connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged); + connect(pm3, &PM3Process::PM3StatedChanged, util, &Util::setRunningState); connect(this, &MainWindow::killPM3, pm3, &PM3Process::kill); connect(util, &Util::write, pm3, &PM3Process::write); From 862f0775f8e9418b5ec3757b921b6020594c1b73 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Wed, 12 Aug 2020 12:30:15 +0800 Subject: [PATCH 3/7] Shorten the waitTime for execCMDWithOutput() --- common/util.cpp | 22 +++++++++++++++++++--- common/util.h | 24 +++++++++++++++++++++++- module/mifare.cpp | 7 ++++--- ui/mainwindow.cpp | 15 ++++++++++++--- ui/mainwindow.h | 3 +++ 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/common/util.cpp b/common/util.cpp index 707dfe7..bb4f3ab 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -27,22 +27,38 @@ void Util::execCMD(QString cmd) emit write(cmd + "\r\n"); } -QString Util::execCMDWithOutput(QString cmd, unsigned long waitTime) +QString Util::execCMDWithOutput(QString cmd, ReturnTrigger trigger) { + bool isResultFound = false; + QRegularExpression re; + re.setPatternOptions(QRegularExpression::DotMatchesEverythingOption); + if(!isRunning) return ""; QTime currTime = QTime::currentTime(); - QTime targetTime = QTime::currentTime().addMSecs(waitTime); + QTime targetTime = QTime::currentTime().addMSecs(trigger.waitTime); isRequiringOutput = true; requiredOutput->clear(); execCMD(cmd); while(QTime::currentTime() < targetTime) { QApplication::processEvents(); + for(QString otpt : trigger.expectedOutputs) + { + re.setPattern(otpt); + isResultFound = re.match(*requiredOutput).hasMatch(); + if(requiredOutput->contains(otpt)) + break; + } + if(isResultFound) + { + delay(200); + break; + } if(timeStamp > currTime) { currTime = timeStamp; - targetTime = timeStamp.addMSecs(waitTime); + targetTime = timeStamp.addMSecs(trigger.waitTime); } } isRequiringOutput = false; diff --git a/common/util.h b/common/util.h index b2ca006..bbf935a 100644 --- a/common/util.h +++ b/common/util.h @@ -9,6 +9,7 @@ #include #include #include +#include class Util : public QObject { @@ -20,12 +21,33 @@ public: CLIENTTYPE_ICEMAN, }; + struct ReturnTrigger + { + unsigned long waitTime; + QStringList expectedOutputs; + ReturnTrigger(unsigned long time) + { + waitTime = time; + expectedOutputs = QStringList(); + } + ReturnTrigger(QStringList outputs) + { + waitTime = 10000; + expectedOutputs = outputs; + } + ReturnTrigger(unsigned long time, QStringList outputs) + { + waitTime = time; + expectedOutputs = outputs; + } + }; + Q_ENUM(Util::ClientType) explicit Util(QObject *parent = nullptr); void execCMD(QString cmd); - QString execCMDWithOutput(QString cmd, unsigned long waitTime = 2000); + QString execCMDWithOutput(QString cmd, ReturnTrigger trigger = 10000); void delay(unsigned int msec); ClientType getClientType(); public slots: diff --git a/module/mifare.cpp b/module/mifare.cpp index a82816b..92d377e 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -119,7 +119,7 @@ void Mifare::chk() "hf mf chk *" + QString::number(cardType.type) + " ?", - 1000 + cardType.type * 1000); + Util::ReturnTrigger(1000 + cardType.sector_size * 200, {"No valid", "\\|---\\|----------------\\|----------------\\|"})); qDebug() << result; int offset = 0; @@ -183,7 +183,8 @@ void Mifare::nested() result = util->execCMDWithOutput( "hf mf nested " + QString::number(cardType.type) - + " *", 10000); + + " *", + Util::ReturnTrigger(10000, {"Can't found", "\\|000\\|"})); } else if(util->getClientType() == Util::CLIENTTYPE_ICEMAN) { @@ -624,7 +625,7 @@ void Mifare::writeSelected(TargetType targetType) continue; else if(choice == QMessageBox::YesToAll) yes2All = true; - else if(QMessageBox::NoToAll) + else if(choice == QMessageBox::NoToAll) { no2All = true; continue; diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 8fbbd8a..aac66f5 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -125,6 +125,10 @@ void MainWindow::refreshCMD(const QString& cmd) ui->Raw_CMDHistoryWidget->addItem(cmd); } +void MainWindow::on_stopButton_clicked() +{ + +} // ********************************************************* // ******************** raw command ******************** @@ -798,12 +802,15 @@ void MainWindow::uiInit() connectStatusBar = new QLabel(this); programStatusBar = new QLabel(this); PM3VersionBar = new QLabel(this); + stopButton = new QPushButton(this); setStatusBar(connectStatusBar, tr("Not Connected")); setStatusBar(programStatusBar, tr("Idle")); setStatusBar(PM3VersionBar, ""); + stopButton->setText(tr("Stop")); ui->statusbar->addPermanentWidget(PM3VersionBar, 1); ui->statusbar->addPermanentWidget(connectStatusBar, 1); ui->statusbar->addPermanentWidget(programStatusBar, 1); + ui->statusbar->addPermanentWidget(stopButton); ui->MF_dataWidget->setColumnCount(3); ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec"))); @@ -812,7 +819,7 @@ void MainWindow::uiInit() ui->MF_dataWidget->verticalHeader()->setVisible(false); ui->MF_dataWidget->setColumnWidth(0, 55); ui->MF_dataWidget->setColumnWidth(1, 55); - ui->MF_dataWidget->setColumnWidth(2, 430); + ui->MF_dataWidget->setColumnWidth(2, 450); ui->MF_keyWidget->setColumnCount(3); ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec"))); @@ -820,8 +827,8 @@ void MainWindow::uiInit() ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB"))); ui->MF_keyWidget->verticalHeader()->setVisible(false); ui->MF_keyWidget->setColumnWidth(0, 35); - ui->MF_keyWidget->setColumnWidth(1, 115); - ui->MF_keyWidget->setColumnWidth(2, 115); + ui->MF_keyWidget->setColumnWidth(1, 125); + ui->MF_keyWidget->setColumnWidth(2, 125); MF_widgetReset(); typeBtnGroup = new QButtonGroup(this); @@ -887,6 +894,8 @@ void MainWindow::signalInit() connect(ui->MF_UIDGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked); connect(ui->MF_simGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked); connect(ui->MF_sniffGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked); + + connect(stopButton, &QPushButton::clicked, this, &MainWindow::on_stopButton_clicked); } void MainWindow::setStatusBar(QLabel * target, const QString & text) diff --git a/ui/mainwindow.h b/ui/mainwindow.h index 873f6d4..55c8c6f 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "common/pm3process.h" #include "module/mifare.h" @@ -148,12 +149,14 @@ private slots: void on_MF_selectTrailerBox_stateChanged(int arg1); + void on_stopButton_clicked(); private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; QLabel* connectStatusBar; QLabel* programStatusBar; QLabel* PM3VersionBar; + QPushButton* stopButton; QAction* myInfo; QAction* checkUpdate; QSettings* settings; From f2d00ee0888c9c8e9cee3aabd049e5f92c14a103 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Thu, 13 Aug 2020 09:30:47 +0800 Subject: [PATCH 4/7] Replace QString with const QString& --- common/pm3process.cpp | 3 +-- common/pm3process.h | 8 ++++---- common/util.cpp | 6 +++--- common/util.h | 12 ++++++------ module/mifare.cpp | 16 ++++++++-------- module/mifare.h | 10 +++++----- ui/mainwindow.cpp | 8 ++++---- ui/mainwindow.h | 16 ++++++++-------- ui/mf_attack_hardnesteddialog.h | 5 +++-- ui/mf_sim_simdialog.h | 2 +- ui/mf_trailerdecoderdialog.h | 4 ++-- ui/mf_uid_parameterdialog.h | 5 +++-- 12 files changed, 48 insertions(+), 47 deletions(-) diff --git a/common/pm3process.cpp b/common/pm3process.cpp index 08aef5a..8181353 100644 --- a/common/pm3process.cpp +++ b/common/pm3process.cpp @@ -14,7 +14,7 @@ PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent) connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead); } -void PM3Process::connectPM3(const QString path, const QString port) +void PM3Process::connectPM3(const QString& path, const QString& port) { QString result; Util::ClientType clientType = Util::CLIENTTYPE_OFFICIAL; @@ -93,7 +93,6 @@ void PM3Process::testThread() qDebug() << "PM3:" << QThread::currentThread(); } - qint64 PM3Process::write(QString data) { return QProcess::write(data.toLatin1()); diff --git a/common/pm3process.h b/common/pm3process.h index 093ebfd..749c501 100644 --- a/common/pm3process.h +++ b/common/pm3process.h @@ -21,8 +21,8 @@ public: void testThread(); public slots: - void connectPM3(const QString path, const QString port); - void setSerialListener(const QString &name, bool state); + void connectPM3(const QString& path, const QString& port); + void setSerialListener(const QString& name, bool state); qint64 write(QString data); private slots: void onTimeout(); @@ -34,8 +34,8 @@ private: QTimer* serialListener; QSerialPortInfo* portInfo; signals: - void PM3StatedChanged(bool st, QString info = ""); - void newOutput(QString output); + void PM3StatedChanged(bool st, const QString& info = ""); + void newOutput(const QString& output); void changeClientType(Util::ClientType); }; diff --git a/common/util.cpp b/common/util.cpp index bb4f3ab..1da8256 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -9,7 +9,7 @@ Util::Util(QObject *parent) : QObject(parent) qRegisterMetaType("Util::ClientType"); } -void Util::processOutput(QString output) +void Util::processOutput(const QString& output) { // qDebug() << "Util::processOutput:" << output; if(isRequiringOutput) @@ -20,14 +20,14 @@ void Util::processOutput(QString output) emit refreshOutput(output); } -void Util::execCMD(QString cmd) +void Util::execCMD(const QString& cmd) { qDebug() << cmd; if(isRunning) emit write(cmd + "\r\n"); } -QString Util::execCMDWithOutput(QString cmd, ReturnTrigger trigger) +QString Util::execCMDWithOutput(const QString& cmd, ReturnTrigger trigger) { bool isResultFound = false; QRegularExpression re; diff --git a/common/util.h b/common/util.h index bbf935a..04a4ec0 100644 --- a/common/util.h +++ b/common/util.h @@ -30,12 +30,12 @@ public: waitTime = time; expectedOutputs = QStringList(); } - ReturnTrigger(QStringList outputs) + ReturnTrigger(const QStringList& outputs) { waitTime = 10000; expectedOutputs = outputs; } - ReturnTrigger(unsigned long time, QStringList outputs) + ReturnTrigger(unsigned long time, const QStringList& outputs) { waitTime = time; expectedOutputs = outputs; @@ -46,12 +46,12 @@ public: explicit Util(QObject *parent = nullptr); - void execCMD(QString cmd); - QString execCMDWithOutput(QString cmd, ReturnTrigger trigger = 10000); + void execCMD(const QString& cmd); + QString execCMDWithOutput(const QString& cmd, ReturnTrigger trigger = 10000); void delay(unsigned int msec); ClientType getClientType(); public slots: - void processOutput(QString output); + void processOutput(const QString& output); void setClientType(Util::ClientType clientType); void setRunningState(bool st); @@ -63,7 +63,7 @@ private: ClientType clientType; signals: void refreshOutput(const QString& output); - void write(QString data); + void write(QString data); // connected to PM3Process::write(QString data); }; #endif // UTIL_H diff --git a/module/mifare.cpp b/module/mifare.cpp index 92d377e..b07593e 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -872,7 +872,7 @@ void Mifare::data_clearKey(bool clearAll) } } -bool Mifare::data_isKeyValid(const QString &key) +bool Mifare::data_isKeyValid(const QString& key) { if(key.length() != 12) return false; @@ -938,7 +938,7 @@ void Mifare::setCardType(int type) } } -bool Mifare::data_loadDataFile(const QString &filename) +bool Mifare::data_loadDataFile(const QString& filename) { QFile file(filename, this); if(file.open(QIODevice::ReadOnly)) @@ -985,7 +985,7 @@ 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)) @@ -1022,7 +1022,7 @@ 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; @@ -1040,7 +1040,7 @@ 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)) @@ -1084,7 +1084,7 @@ 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)) @@ -1179,12 +1179,12 @@ void Mifare::data_data2Key() } } -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, KeyType keyType, const QString &key) +void Mifare::data_setKey(int sector, KeyType keyType, const QString& key) { if(keyType == KEY_A) keyAList->replace(sector, key); diff --git a/module/mifare.h b/module/mifare.h index b328314..dfde298 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -106,9 +106,9 @@ public: void saveSniff(const QString& file); void data_fillKeys(); - static QList data_getACBits(const QString &text); + static QList data_getACBits(const QString& text); static int data_b2s(int block); - static bool data_isACBitsValid(const QString &text, QList *returnHalfBytes = nullptr); + static bool data_isACBitsValid(const QString& text, QList *returnHalfBytes = nullptr); public slots: signals: @@ -125,9 +125,9 @@ private: QRegularExpression* keyPattern; QString bin2text(const QByteArray& buff, int start, int length); - QString _readblk(int blockId, KeyType keyType, const QString &key, TargetType targetType = TARGET_MIFARE, int waitTime = 300); - QStringList _readsec(int sectorId, KeyType keyType, const QString &key, TargetType targetType = TARGET_MIFARE, int waitTime = 300); - bool _writeblk(int blockId, KeyType keyType, const QString &key, const QString &data, TargetType targetType = TARGET_MIFARE, int waitTime = 300); + QString _readblk(int blockId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300); + QStringList _readsec(int sectorId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300); + bool _writeblk(int blockId, KeyType keyType, const QString& key, const QString& data, TargetType targetType = TARGET_MIFARE, int waitTime = 300); }; #endif // MIFARE_H diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index aac66f5..421a019 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -86,7 +86,7 @@ void MainWindow::on_PM3_connectButton_clicked() } } -void MainWindow::onPM3StateChanged(bool st, QString info) +void MainWindow::onPM3StateChanged(bool st, const QString& info) { pm3state = st; setState(st); @@ -898,7 +898,7 @@ void MainWindow::signalInit() connect(stopButton, &QPushButton::clicked, this, &MainWindow::on_stopButton_clicked); } -void MainWindow::setStatusBar(QLabel * target, const QString & text) +void MainWindow::setStatusBar(QLabel * target, const QString& text) { if(target == PM3VersionBar) target->setText(tr("HW Version:") + text); @@ -908,7 +908,7 @@ void MainWindow::setStatusBar(QLabel * target, const QString & text) target->setText(tr("State:") + text); } -void MainWindow::setTableItem(QTableWidget * widget, int row, int column, const QString & text) +void MainWindow::setTableItem(QTableWidget * widget, int row, int column, const QString& text) { if(widget->item(row, column) == nullptr) widget->setItem(row, column, new QTableWidgetItem()); @@ -993,7 +993,7 @@ void MainWindow::on_GroupBox_clicked(bool checked) settings->endGroup(); } -void MainWindow::saveClientPath(const QString & path) +void MainWindow::saveClientPath(const QString& path) { settings->beginGroup("Client_Path"); settings->setValue("path", path); diff --git a/ui/mainwindow.h b/ui/mainwindow.h index 55c8c6f..2c7fcd5 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -44,10 +44,10 @@ public: void initUI(); bool eventFilter(QObject *watched, QEvent *event); public slots: - void refreshOutput(const QString &output); - void refreshCMD(const QString &cmd); - void setStatusBar(QLabel* target, const QString & text); - void onPM3StateChanged(bool st, QString info); + void refreshOutput(const QString& output); + void refreshCMD(const QString& cmd); + void setStatusBar(QLabel* target, const QString& text); + void onPM3StateChanged(bool st, const QString& info); void MF_onTypeChanged(int id, bool st); private slots: @@ -175,12 +175,12 @@ private: void signalInit(); void MF_widgetReset(); - void setTableItem(QTableWidget *widget, int row, int column, const QString &text); + void setTableItem(QTableWidget *widget, int row, int column, const QString& text); void setState(bool st); - void saveClientPath(const QString &path); + void saveClientPath(const QString& path); signals: - void connectPM3(const QString path, const QString port); + void connectPM3(const QString& path, const QString& port); void killPM3(); - void setSerialListener(const QString &name, bool state); + void setSerialListener(const QString& name, bool state); }; #endif // MAINWINDOW_H diff --git a/ui/mf_attack_hardnesteddialog.h b/ui/mf_attack_hardnesteddialog.h index 0f13bf7..d120b2a 100644 --- a/ui/mf_attack_hardnesteddialog.h +++ b/ui/mf_attack_hardnesteddialog.h @@ -3,7 +3,8 @@ #include -namespace Ui { +namespace Ui +{ class MF_Attack_hardnestedDialog; } @@ -19,7 +20,7 @@ public: private: Ui::MF_Attack_hardnestedDialog *ui; signals: - void sendCMD(QString cmd); + void sendCMD(const QString& cmd); private slots: void on_buttonBox_accepted(); }; diff --git a/ui/mf_sim_simdialog.h b/ui/mf_sim_simdialog.h index 7fa53a1..49c9ba2 100644 --- a/ui/mf_sim_simdialog.h +++ b/ui/mf_sim_simdialog.h @@ -26,7 +26,7 @@ private: Ui::MF_Sim_simDialog *ui; int cardType; signals: - void sendCMD(QString cmd); + void sendCMD(const QString& cmd); private slots: void on_buttonBox_accepted(); }; diff --git a/ui/mf_trailerdecoderdialog.h b/ui/mf_trailerdecoderdialog.h index 93a6abd..e863f1c 100644 --- a/ui/mf_trailerdecoderdialog.h +++ b/ui/mf_trailerdecoderdialog.h @@ -23,11 +23,11 @@ public: private slots: - void on_accessBitsEdit_textChanged(const QString &arg1); + void on_accessBitsEdit_textChanged(const QString& arg1); void on_blockSizeChanged(int id, bool st); - void on_boxChanged(const QString &arg1); + void on_boxChanged(const QString& arg1); private: Ui::MF_trailerDecoderDialog *ui; QRegularExpressionValidator* validator; diff --git a/ui/mf_uid_parameterdialog.h b/ui/mf_uid_parameterdialog.h index ec580cb..85e9fc0 100644 --- a/ui/mf_uid_parameterdialog.h +++ b/ui/mf_uid_parameterdialog.h @@ -3,7 +3,8 @@ #include -namespace Ui { +namespace Ui +{ class MF_UID_parameterDialog; } @@ -18,7 +19,7 @@ public: private: Ui::MF_UID_parameterDialog *ui; signals: - void sendCMD(QString cmd); + void sendCMD(const QString& cmd); private slots: void on_buttonBox_accepted(); }; From 2f38d3c8c54e8275f8f5d4bd23c33a50c0e8b537 Mon Sep 17 00:00:00 2001 From: wh201906 Date: Thu, 13 Aug 2020 16:39:04 +0800 Subject: [PATCH 5/7] Support choose history command by Key_Up and Key_Down --- Proxmark3GUI.pro | 2 ++ common/myeventfilter.cpp | 13 +++++++++++++ common/myeventfilter.h | 22 ++++++++++++++++++++++ ui/mainwindow.cpp | 38 ++++++++++++++++++++++++++++++++++++++ ui/mainwindow.h | 8 ++++++++ ui/mainwindow.ui | 5 ++++- 6 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 common/myeventfilter.cpp create mode 100644 common/myeventfilter.h diff --git a/Proxmark3GUI.pro b/Proxmark3GUI.pro index 85feb73..08abf01 100644 --- a/Proxmark3GUI.pro +++ b/Proxmark3GUI.pro @@ -16,6 +16,7 @@ DEFINES += QT_DEPRECATED_WARNINGS #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ + common/myeventfilter.cpp \ main.cpp \ common/pm3process.cpp \ common/util.cpp \ @@ -27,6 +28,7 @@ SOURCES += \ ui/mf_attack_hardnesteddialog.cpp \ HEADERS += \ + common/myeventfilter.h \ common/pm3process.h \ common/util.h \ module/mifare.h \ diff --git a/common/myeventfilter.cpp b/common/myeventfilter.cpp new file mode 100644 index 0000000..b717ca3 --- /dev/null +++ b/common/myeventfilter.cpp @@ -0,0 +1,13 @@ +#include "myeventfilter.h" + +MyEventFilter::MyEventFilter(QEvent::Type filter) +{ + targetEventType = filter; +} + +bool MyEventFilter::eventFilter(QObject *obj, QEvent *event) +{ + if(event->type() == targetEventType) + emit eventHappened(obj, *event); + return QObject::eventFilter(obj, event); +} diff --git a/common/myeventfilter.h b/common/myeventfilter.h new file mode 100644 index 0000000..3ab624a --- /dev/null +++ b/common/myeventfilter.h @@ -0,0 +1,22 @@ +#ifndef MYEVENTFILTER_H +#define MYEVENTFILTER_H + +#include +#include + +class MyEventFilter : public QObject +{ + Q_OBJECT + +public: + explicit MyEventFilter(QEvent::Type filter); +protected: + bool eventFilter(QObject *obj, QEvent *event) override; + +signals: + void eventHappened(QObject* obj_addr, QEvent& event); +private: + QEvent::Type targetEventType; +}; + +#endif // MYEVENTFILTER_H diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 421a019..f3dbaac 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -29,6 +29,7 @@ MainWindow::MainWindow(QWidget *parent): util = new Util(this); mifare = new Mifare(ui, util, this); + keyEventFilter = new MyEventFilter(QEvent::KeyRelease); } MainWindow::~MainWindow() @@ -177,6 +178,36 @@ void MainWindow::sendMSG() // send command when pressing Enter on_Raw_sendCMDButton_clicked(); } +void MainWindow::on_Raw_CMDEdit_keyPressed(QObject* obj_addr, QEvent& event) +{ + if(obj_addr == ui->Raw_CMDEdit && event.type() == QEvent::KeyRelease) + { + QKeyEvent& keyEvent = static_cast(event); + if(keyEvent.key() == Qt::Key_Up) + { + if(stashedIndex > 0) + stashedIndex--; + else if(stashedIndex == -1) + stashedIndex = ui->Raw_CMDHistoryWidget->count() - 1; + } + else if(keyEvent.key() == Qt::Key_Down) + { + if(stashedIndex < ui->Raw_CMDHistoryWidget->count() - 1 && stashedIndex != -1) + stashedIndex++; + else if(stashedIndex == ui->Raw_CMDHistoryWidget->count() - 1) + stashedIndex = -1; + } + if(keyEvent.key() == Qt::Key_Up || keyEvent.key() == Qt::Key_Down) + { + ui->Raw_CMDEdit->blockSignals(true); + if(stashedIndex == -1) + ui->Raw_CMDEdit->setText(stashedCMDEditText); + else + ui->Raw_CMDEdit->setText(ui->Raw_CMDHistoryWidget->item(stashedIndex)->text()); + ui->Raw_CMDEdit->blockSignals(false); + } + } +} // ***************************************************** // ******************** mifare ******************** @@ -798,6 +829,8 @@ void MainWindow::MF_widgetReset() void MainWindow::uiInit() { connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG); + ui->Raw_CMDEdit->installEventFilter(keyEventFilter); + connect(keyEventFilter, &MyEventFilter::eventHappened, this, &MainWindow::on_Raw_CMDEdit_keyPressed); connectStatusBar = new QLabel(this); programStatusBar = new QLabel(this); @@ -1000,3 +1033,8 @@ void MainWindow::saveClientPath(const QString& path) settings->endGroup(); } // *********************************************** + +void MainWindow::on_Raw_CMDEdit_textChanged(const QString &arg1) +{ + stashedCMDEditText = arg1; +} diff --git a/ui/mainwindow.h b/ui/mainwindow.h index 2c7fcd5..91daafa 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -21,6 +21,7 @@ #include #include +#include "common/myeventfilter.h" #include "common/pm3process.h" #include "module/mifare.h" #include "common/util.h" @@ -49,6 +50,7 @@ public slots: void setStatusBar(QLabel* target, const QString& text); void onPM3StateChanged(bool st, const QString& info); void MF_onTypeChanged(int id, bool st); + void on_Raw_CMDEdit_keyPressed(QObject *obj_addr, QEvent &event); private slots: void on_PM3_connectButton_clicked(); @@ -150,6 +152,8 @@ private slots: void on_MF_selectTrailerBox_stateChanged(int arg1); void on_stopButton_clicked(); + void on_Raw_CMDEdit_textChanged(const QString &arg1); + private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; @@ -160,6 +164,10 @@ private: QAction* myInfo; QAction* checkUpdate; QSettings* settings; + MyEventFilter* keyEventFilter; + + QString stashedCMDEditText; + int stashedIndex = -1; void uiInit(); diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index edd93f4..3279bd5 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -120,7 +120,7 @@ - 0 + 1 @@ -1198,6 +1198,9 @@ 0 + + Qt::NoFocus + Qt::ScrollBarAlwaysOn From 73533608e6470b498f55fc4394e8d15dbc25ab9c Mon Sep 17 00:00:00 2001 From: wh201906 Date: Fri, 14 Aug 2020 00:46:07 +0800 Subject: [PATCH 6/7] Add some useless UI --- ui/mainwindow.cpp | 19 +++-- ui/mainwindow.ui | 213 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 7 deletions(-) diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index f3dbaac..6ad89ba 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -119,13 +119,6 @@ void MainWindow::refreshOutput(const QString& output) ui->Raw_outputEdit->moveCursor(QTextCursor::End); } -void MainWindow::refreshCMD(const QString& cmd) -{ - ui->Raw_CMDEdit->setText(cmd); - if(cmd != "" && (ui->Raw_CMDHistoryWidget->count() == 0 || ui->Raw_CMDHistoryWidget->item(ui->Raw_CMDHistoryWidget->count() - 1)->text() != cmd)) - ui->Raw_CMDHistoryWidget->addItem(cmd); -} - void MainWindow::on_stopButton_clicked() { @@ -178,6 +171,18 @@ void MainWindow::sendMSG() // send command when pressing Enter on_Raw_sendCMDButton_clicked(); } + +void MainWindow::refreshCMD(const QString& cmd) +{ + ui->Raw_CMDEdit->blockSignals(true); + ui->Raw_CMDEdit->setText(cmd); + if(cmd != "" && (ui->Raw_CMDHistoryWidget->count() == 0 || ui->Raw_CMDHistoryWidget->item(ui->Raw_CMDHistoryWidget->count() - 1)->text() != cmd)) + ui->Raw_CMDHistoryWidget->addItem(cmd); + stashedCMDEditText = cmd; + stashedIndex = -1; + ui->Raw_CMDEdit->blockSignals(false); +} + void MainWindow::on_Raw_CMDEdit_keyPressed(QObject* obj_addr, QEvent& event) { if(obj_addr == ui->Raw_CMDEdit && event.type() == QEvent::KeyRelease) diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 3279bd5..5207ec6 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -1168,6 +1168,219 @@ + + + LF/Data + + + + + 30 + 30 + 121 + 211 + + + + LF Config + + + + 2 + + + 2 + + + 5 + + + 2 + + + 2 + + + + + Frequency + + + + 5 + + + 2 + + + 5 + + + 2 + + + 2 + + + + + + 0 + 0 + + + + 125k + + + + + + + + 0 + 0 + + + + 134k + + + + + + + + + + + + BitRate: + + + + + + + Decimation: + + + + + + + + + + Averaging: + + + + + + + + + + + + + + Threshold: + + + + + + + + + + Skips: + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + Get + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + Set + + + + + + + + + + + T55xx + + + + + 20 + 10 + 256 + 192 + + + + RawCommand From 3c3944d150d86b8517795657313044069afcf78f Mon Sep 17 00:00:00 2001 From: wh201906 Date: Sun, 1 Nov 2020 22:43:46 +0800 Subject: [PATCH 7/7] Slight change --- ui/mainwindow.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 5207ec6..2e7cc0b 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -1175,8 +1175,8 @@ - 30 - 30 + 10 + 10 121 211