diff --git a/common/pm3process.cpp b/common/pm3process.cpp index a3435f8..5939be4 100644 --- a/common/pm3process.cpp +++ b/common/pm3process.cpp @@ -11,6 +11,7 @@ PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent) serialListener->setInterval(1000); serialListener->setTimerType(Qt::VeryCoarseTimer); connect(serialListener,&QTimer::timeout,this,&PM3Process::onTimeout); + connect(this,&PM3Process::readyRead,this,&PM3Process::onReadyRead); } void PM3Process::connectPM3(const QString path, const QString port) @@ -44,18 +45,6 @@ void PM3Process::setRequiringOutput(bool st) if(isRequiringOutput) requiredOutput->clear(); } -QByteArray PM3Process::readLine(qint64 maxlen) -{ - QByteArray buff; - buff=QProcess::readLine(maxlen); - if(isRequiringOutput) - requiredOutput->append(buff); - return buff; -} -QString PM3Process::getRequiredOutput() -{ - return *requiredOutput; -} bool PM3Process::waitForReadyRead(int msecs) { @@ -77,7 +66,7 @@ void PM3Process::setSerialListener(const QString& name,bool state) } } -void PM3Process::onTimeout() //when the proxmark3 client is unexpectedly terminated or the PM3 hardware is removed, the isBusy() will return false(tested on Windows); +void PM3Process::onTimeout() //when the proxmark3 client is unexpectedly terminated or the PM3 hardware is removed, the isBusy() will return false(only tested on Windows); { qDebug()<isBusy(); if(!portInfo->isBusy()) @@ -101,12 +90,13 @@ qint64 PM3Process::write(QString data) void PM3Process::onReadyRead() { - QString btay = readLine(); -// while(btay != "") -// { -// qDebug() << btay; -// ui->Raw_outputEdit->insertPlainText(btay); -// btay = pm3->readLine(); -// } -// ui->Raw_outputEdit->moveCursor(QTextCursor::End); + QString out = readAll(); + if(isRequiringOutput) + requiredOutput->append(out); + if(out != "") + { + qDebug()<<"PM3Process::onReadyRead:" << out; + emit newOutput(out); + + } } diff --git a/common/pm3process.h b/common/pm3process.h index 444babb..b6fd099 100644 --- a/common/pm3process.h +++ b/common/pm3process.h @@ -14,14 +14,11 @@ class PM3Process : public QProcess Q_OBJECT public: explicit PM3Process(QThread* thread, QObject* parent=nullptr); - QByteArray readLine(qint64 maxlen = 0); - QString getRequiredOutput(); bool waitForReadyRead(int msecs = 2000); void testThread(); public slots: - void setRequiringOutput(bool st); void connectPM3(const QString path, const QString port); void setSerialListener(const QString &name, bool state); qint64 write(QString data); @@ -30,7 +27,8 @@ private slots: void onReadyRead(); private: bool isRequiringOutput; - QString* requiredOutput; + QString* requiredOutput; // It only works in this class now + void setRequiringOutput(bool st);// It only works in this class now QTimer* serialListener; QSerialPortInfo* portInfo; signals: diff --git a/common/util.cpp b/common/util.cpp index 1a0415d..e9da6cb 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -2,10 +2,51 @@ Util::Util(QObject *parent) : QObject(parent) { + isRequiringOutput=false; + requiredOutput=new QString(); + timeStamp=QTime::currentTime(); +} +void Util::processOutput(QString output) +{ + qDebug()<<"Util::processOutput:" << output; + if(isRequiringOutput) + { + requiredOutput->append(output); + timeStamp=QTime::currentTime(); + } + emit refreshOutput(output); } -void Util::processOutput() +void Util::execCMD(QString cmd) { + qDebug() << cmd; + emit write(cmd + "\r\n"); +} +QString Util::execCMDWithOutput(QString cmd, unsigned long timeout) +{ + QTime currTime=QTime::currentTime(); + QTime targetTime = QTime::currentTime().addMSecs(timeout); + isRequiringOutput=true; + requiredOutput->clear(); + execCMD(cmd); + while( QTime::currentTime() < targetTime) + { + QApplication::processEvents(); + if(timeStamp>currTime) + { + currTime=timeStamp; + targetTime=timeStamp.addMSecs(timeout); + } + } + isRequiringOutput=false; + return *requiredOutput; +} + +void Util::delay(unsigned int msec) +{ + QTime timer = QTime::currentTime().addMSecs(msec); + while( QTime::currentTime() < timer ) + QApplication::processEvents(QEventLoop::AllEvents, 100); } diff --git a/common/util.h b/common/util.h index d935aa2..0e4c792 100644 --- a/common/util.h +++ b/common/util.h @@ -2,6 +2,12 @@ #define UTIL_H #include +#include +#include +#include +#include +#include +#include class Util : public QObject { @@ -9,10 +15,19 @@ class Util : public QObject public: explicit Util(QObject *parent = nullptr); -signals: + void execCMD(QString cmd); + QString execCMDWithOutput(QString cmd, unsigned long timeout=2000); + void delay(unsigned int msec); +public slots: + void processOutput(QString output); -private slots: - void processOutput(); +private: + bool isRequiringOutput; + QString* requiredOutput; + QTime timeStamp; +signals: + void refreshOutput(const QString& output); + void write(QString data); }; #endif // UTIL_H diff --git a/module/mifare.cpp b/module/mifare.cpp index 4db8426..2ae101a 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -46,3 +46,15 @@ void Mifare::setInputType(InputType tp) { inputType=tp; } + +bool Mifare::isKeyValid(const QString key) +{ + if(key.length() != 12) + return false; + for(int i = 0; i < 12; i++) + { + if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F'))) + return false; + } + return true; +} diff --git a/module/mifare.h b/module/mifare.h index 9c68719..9a7d473 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -3,6 +3,7 @@ #include "common/util.h" #include +#include class Mifare : public QObject { @@ -25,6 +26,7 @@ public: void setProcessingState(ProcessingState st); void setInputType(InputType tp); + bool isKeyValid(const QString key); public slots: void processData(const QString str); void processKey(const QString str); diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index f3e1400..659a8fc 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -97,7 +97,7 @@ void MainWindow::on_PM3_disconnectButton_clicked() void MainWindow::on_Raw_sendCMDButton_clicked() { - execCMD(ui->Raw_CMDEdit->text()); + util->execCMD(ui->Raw_CMDEdit->text()); } void MainWindow::on_Raw_clearOutputButton_clicked() @@ -138,12 +138,13 @@ void MainWindow::on_Raw_CMDHistoryWidget_itemDoubleClicked(QListWidgetItem *item void MainWindow::on_MF_Attack_infoButton_clicked() { - execCMD("hf 14a info", true); + util->execCMD("hf 14a info"); + ui->funcTab->setCurrentIndex(1); } void MainWindow::on_MF_Attack_chkButton_clicked() { - QString result = execCMDWithOutput("hf mf chk *1 ?"); + 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++) @@ -156,7 +157,7 @@ void MainWindow::on_MF_Attack_chkButton_clicked() void MainWindow::on_MF_Attack_nestedButton_clicked() { - QString result = execCMDWithOutput("hf mf nested 1 *"); + 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++) @@ -172,18 +173,21 @@ void MainWindow::on_MF_Attack_nestedButton_clicked() void MainWindow::on_MF_Attack_hardnestedButton_clicked() { MF_Attack_hardnestedDialog dialog; - connect(&dialog, &MF_Attack_hardnestedDialog::sendCMD, this, &MainWindow::execCMD); - dialog.exec(); + connect(&dialog, &MF_Attack_hardnestedDialog::sendCMD, util, &Util::execCMD); + if(dialog.exec()==QDialog::Accepted) + ui->funcTab->setCurrentIndex(1); } void MainWindow::on_MF_Attack_sniffButton_clicked() { - execCMD("hf mf sniff", true); + util->execCMD("hf mf sniff"); + ui->funcTab->setCurrentIndex(1); } void MainWindow::on_MF_Attack_listButton_clicked() { - execCMD("hf list mf", true); + util->execCMD("hf list mf"); + ui->funcTab->setCurrentIndex(1); } void MainWindow::on_MF_RW_readAllButton_clicked() @@ -200,9 +204,9 @@ void MainWindow::on_MF_RW_readAllButton_clicked() isKeyBValid = false; // check keys and read the first block of each sector - if(ui->MF_keyWidget->item(i, 1) != nullptr && MF_isKeyValid(ui->MF_keyWidget->item(i, 1)->text())) + if(ui->MF_keyWidget->item(i, 1) != nullptr && mifare->isKeyValid(ui->MF_keyWidget->item(i, 1)->text())) { - result = execCMDWithOutput("hf mf rdbl " + result = util->execCMDWithOutput("hf mf rdbl " + QString::number(4 * i) + " A " + ui->MF_keyWidget->item(i, 1)->text(), waitTime); @@ -213,9 +217,9 @@ void MainWindow::on_MF_RW_readAllButton_clicked() } } QApplication::processEvents(); - if(ui->MF_keyWidget->item(i, 2) != nullptr && MF_isKeyValid(ui->MF_keyWidget->item(i, 2)->text())) + if(ui->MF_keyWidget->item(i, 2) != nullptr && mifare->isKeyValid(ui->MF_keyWidget->item(i, 2)->text())) { - result = execCMDWithOutput("hf mf rdbl " + result = util->execCMDWithOutput("hf mf rdbl " + QString::number(4 * i) + " B " + ui->MF_keyWidget->item(i, 2)->text(), waitTime); @@ -232,7 +236,7 @@ void MainWindow::on_MF_RW_readAllButton_clicked() for(int j = 1; j < 4; j++) { QApplication::processEvents(); - result = execCMDWithOutput("hf mf rdbl " + result = util->execCMDWithOutput("hf mf rdbl " + QString::number(4 * i + j) + " " + (isKeyAValid ? "A" : "B") @@ -275,7 +279,7 @@ void MainWindow::on_MF_RW_readAllButton_clicked() else { QString tmpKey = result.right(18).replace(" ", ""); - result = execCMDWithOutput("hf mf rdbl " + result = util->execCMDWithOutput("hf mf rdbl " + QString::number(4 * i + 3) + " B " + tmpKey, waitTime); @@ -297,7 +301,7 @@ void MainWindow::on_MF_RW_readAllButton_clicked() void MainWindow::on_MF_RW_readBlockButton_clicked() { - QString result = execCMDWithOutput("hf mf rdbl " + QString result = util->execCMDWithOutput("hf mf rdbl " + ui->MF_RW_blockBox->currentText() + " " + ui->MF_RW_keyTypeBox->currentText() @@ -316,7 +320,7 @@ void MainWindow::on_MF_RW_readBlockButton_clicked() } ui->MF_RW_dataEdit->setText(result); QString tmpKey = result.right(18).replace(" ", ""); - result = execCMDWithOutput("hf mf rdbl " + result = util->execCMDWithOutput("hf mf rdbl " + ui->MF_RW_keyTypeBox->currentText() + " B " + tmpKey); @@ -343,7 +347,7 @@ void MainWindow::on_MF_RW_readBlockButton_clicked() void MainWindow::on_MF_RW_writeBlockButton_clicked() { - QString result = execCMDWithOutput("hf mf wrbl " + QString result = util->execCMDWithOutput("hf mf wrbl " + ui->MF_RW_blockBox->currentText() + " " + ui->MF_RW_keyTypeBox->currentText() @@ -364,7 +368,7 @@ void MainWindow::on_MF_RW_writeAllButton_clicked() { for(int j = 0; j < 4; j++) { - result = execCMDWithOutput("hf mf wrbl " + result = util->execCMDWithOutput("hf mf wrbl " + QString::number(i * 4 + j) + " A " + ui->MF_keyWidget->item(i, 1)->text() @@ -372,7 +376,7 @@ void MainWindow::on_MF_RW_writeAllButton_clicked() + ui->MF_dataWidget->item(2, i * 4 + j)->text().replace(" ", "")); if(result.indexOf("isOk:01") == -1) { - result = execCMDWithOutput("hf mf wrbl " + result = util->execCMDWithOutput("hf mf wrbl " + QString::number(i * 4 + j) + " B " + ui->MF_keyWidget->item(i, 2)->text() @@ -388,18 +392,20 @@ void MainWindow::on_MF_RW_writeAllButton_clicked() // ******************** other ******************** -void MainWindow::refresh() +void MainWindow::refreshOutput(const QString& output) { - QString btay = pm3->readLine(); - while(btay != "") - { - qDebug() << btay; - ui->Raw_outputEdit->insertPlainText(btay); - btay = pm3->readLine(); - } + qDebug()<<"MainWindow::refresh:" << output; + ui->Raw_outputEdit->insertPlainText(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::sendMSG() { if(ui->Raw_CMDEdit->hasFocus()) @@ -458,14 +464,14 @@ void MainWindow::uiInit() void MainWindow::signalInit() { -// connect(pm3, &PM3Process::readyRead, util, &MainWindow::refresh); + connect(pm3, &PM3Process::newOutput, util, &Util::processOutput); + connect(util,&Util::refreshOutput,this,&MainWindow::refreshOutput); - connect(this,&MainWindow::requiringOutput,pm3,&PM3Process::setRequiringOutput); connect(this,&MainWindow::connectPM3,pm3,&PM3Process::connectPM3); connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged); connect(this,&MainWindow::killPM3,pm3,&PM3Process::kill); - connect(this,&MainWindow::write,pm3,&PM3Process::write); + connect(util,&Util::write,pm3,&PM3Process::write); } void MainWindow::setStatusBar(QLabel* target, const QString & text) @@ -477,39 +483,6 @@ void MainWindow::setStatusBar(QLabel* target, const QString & text) else if(target == programStatusBar) target->setText("Program State:" + text); } - -void MainWindow::execCMD(QString cmd, bool gotoRawTab) -{ - ui->Raw_CMDEdit->setText(cmd); - if(ui->Raw_CMDHistoryWidget->count() == 0 || ui->Raw_CMDHistoryWidget->item(ui->Raw_CMDHistoryWidget->count() - 1)->text() != cmd) - ui->Raw_CMDHistoryWidget->addItem(cmd); - qDebug() << cmd; - emit write(cmd + "\r\n"); - if(gotoRawTab) - ui->funcTab->setCurrentIndex(1); -} - -QString MainWindow::execCMDWithOutput(QString cmd, int msec) -{ - emit requiringOutput(true); - execCMD(cmd); - while(pm3->waitForReadyRead(msec)) - ; - pm3->setRequiringOutput(false); - return pm3->getRequiredOutput(); -} - -bool MainWindow::MF_isKeyValid(const QString key) -{ - if(key.length() != 12) - return false; - for(int i = 0; i < 12; i++) - { - if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F'))) - return false; - } - return true; -} // *********************************************** diff --git a/ui/mainwindow.h b/ui/mainwindow.h index c595fa8..78bc720 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -28,11 +28,10 @@ public: ~MainWindow(); bool MF_isKeyValid(const QString key); - QString execCMDWithOutput(QString cmd, int msec=2000); public slots: - void refresh(); + void refreshOutput(const QString &output); + void refreshCMD(const QString &cmd); void setStatusBar(QLabel* target,const QString & text); - void execCMD(QString cmd, bool gotoRawTab=false); void onPM3StateChanged(bool st, QString info); private slots: @@ -87,10 +86,8 @@ private: QLabel* PM3VersionBar; void signalInit(); signals: - void requiringOutput(bool st); void connectPM3(const QString path, const QString port); void killPM3(); void setSerialListener(const QString &name, bool state); - void write(QString data); }; #endif // MAINWINDOW_H diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 0b6dfe6..d9688e8 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -88,7 +88,7 @@ - 1 + 0 diff --git a/ui/mf_attack_hardnesteddialog.h b/ui/mf_attack_hardnesteddialog.h index d5c066f..74cd17b 100644 --- a/ui/mf_attack_hardnesteddialog.h +++ b/ui/mf_attack_hardnesteddialog.h @@ -19,7 +19,7 @@ public: private: Ui::MF_Attack_hardnestedDialog *ui; signals: - void sendCMD(QString cmd, bool requireJump = true); + void sendCMD(QString cmd); private slots: void on_buttonBox_accepted(); };