diff --git a/Proxmark3GUI.pro b/Proxmark3GUI.pro index b01adb0..f09426d 100644 --- a/Proxmark3GUI.pro +++ b/Proxmark3GUI.pro @@ -20,6 +20,7 @@ SOURCES += \ common/pm3process.cpp \ common/util.cpp \ module/mifare.cpp \ + ui/mf_trailerdecoderdialog.cpp \ ui/mf_sim_simdialog.cpp \ ui/mf_uid_parameterdialog.cpp \ ui/mainwindow.cpp \ @@ -29,12 +30,14 @@ HEADERS += \ common/pm3process.h \ common/util.h \ module/mifare.h \ + ui/mf_trailerdecoderdialog.h \ ui/mf_sim_simdialog.h \ ui/mf_uid_parameterdialog.h \ ui/mainwindow.h \ ui/mf_attack_hardnesteddialog.h \ FORMS += \ + ui/mf_trailerdecoderdialog.ui \ ui/mf_sim_simdialog.ui \ ui/mf_uid_parameterdialog.ui \ ui/mainwindow.ui \ diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 729aee9..f14f9e0 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -904,3 +904,9 @@ void MainWindow::on_testButton_clicked() { mifare->_readsec(0, Mifare::KEY_A, "FFFFFFFFFFFF"); } + +void MainWindow::on_MF_trailerDecoderButton_clicked() +{ + decDialog = new MF_trailerDecoderDialog(this); + decDialog->show(); +} diff --git a/ui/mainwindow.h b/ui/mainwindow.h index f3337b6..1327e0a 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -23,6 +23,7 @@ #include "common/pm3process.h" #include "module/mifare.h" #include "common/util.h" +#include "ui/mf_trailerdecoderdialog.h" QT_BEGIN_NAMESPACE namespace Ui @@ -145,6 +146,8 @@ private slots: void on_testButton_clicked(); + void on_MF_trailerDecoderButton_clicked(); + private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; @@ -163,6 +166,8 @@ private: Mifare* mifare; Util* util; + MF_trailerDecoderDialog* decDialog; + void signalInit(); void MF_widgetReset(); diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index a32006c..cf7518d 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -213,6 +213,13 @@ + + + + Trailer Decoder + + + @@ -630,14 +637,14 @@ - Read Checked + Read Selected - Write Checked + Write Selected @@ -722,14 +729,14 @@ - Read Checked + Read Selected - Write Checked + Write Selected diff --git a/ui/mf_trailerdecoderdialog.cpp b/ui/mf_trailerdecoderdialog.cpp new file mode 100644 index 0000000..327414a --- /dev/null +++ b/ui/mf_trailerdecoderdialog.cpp @@ -0,0 +1,107 @@ +#include "mf_trailerdecoderdialog.h" +#include "ui_mf_trailerdecoderdialog.h" + +MF_trailerDecoderDialog::MF_trailerDecoderDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::MF_trailerDecoderDialog) +{ + ui->setupUi(this); + QRegularExpression re("(([0-9a-fA-F]{2} ){0,4})|([0-9a-fA-F]{0,8})"); + validator = new QRegularExpressionValidator(this); + validator->setRegularExpression(re); + ui->accessBitsEdit->setValidator(validator); + + sizeGroup = new QButtonGroup(this); + sizeGroup->addButton(ui->size4Button, 4); + sizeGroup->addButton(ui->size16Button, 16); + connect(sizeGroup, QOverload::of(&QButtonGroup::buttonToggled), this, &MF_trailerDecoderDialog::on_blockSizeChanged); + + ui->dataBlockWidget->setRowCount(3); + ui->dataBlockWidget->setColumnCount(4); + ui->trailerBlockWidget->setRowCount(2); + ui->trailerBlockWidget->setColumnCount(3); +} + +MF_trailerDecoderDialog::~MF_trailerDecoderDialog() +{ + delete ui; +} +void MF_trailerDecoderDialog::on_accessBitsEdit_textEdited(const QString &arg1) +{ + QString input = arg1; + input.remove(" "); + if(input.length() < 6) + { + ui->isAccessBitsValidLabel->setText(""); + return; + } + input = input.left(6); + quint32 result = input.toUInt(nullptr, 16); + quint8 halfBytes[6]; + for(int i = 0; i < 6; i++) + { + halfBytes[i] = (result >> ((5 - i) * 4)) & 0xf; + } + qDebug() << result; + if((~halfBytes[0] & 0xf) != halfBytes[5] || (~halfBytes[1] & 0xf) != halfBytes[2] || (~halfBytes[3] & 0xf) != halfBytes[4]) + { + ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(200, 0, 0)"); + ui->isAccessBitsValidLabel->setText(tr("Invalid! It could make the whole sector blocked irreversibly!")); + } + else + { + ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(0, 200, 0)"); + ui->isAccessBitsValidLabel->setText(tr("Valid")); + quint8 ACBits[4]; + for(int i = 0; i < 4; i++) + { + ACBits[i] = (((halfBytes[4] >> i) & 1) << 2) & (((halfBytes[5] >> i) & 1) << 1) & (((halfBytes[2] >> i) & 1) << 0); + } + bool isKeyBReadable = ACBits[3] == 0 || ACBits[3] == 1 || ACBits[3] == 4; + setTableItem(ui->trailerBlockWidget, 0, 0, "X"); + } +} + +void MF_trailerDecoderDialog::on_blockSizeChanged(int id, bool st) +{ + if(st) + { + if(id == 4) + { + ui->dataBlockWidget->verticalHeaderItem(0)->setText("Block0"); + ui->dataBlockWidget->verticalHeaderItem(1)->setText("Block1"); + ui->dataBlockWidget->verticalHeaderItem(2)->setText("Block2"); + } + else if(id == 16) + { + ui->dataBlockWidget->verticalHeaderItem(0)->setText("Block0~4"); + ui->dataBlockWidget->verticalHeaderItem(1)->setText("Block5~9"); + ui->dataBlockWidget->verticalHeaderItem(2)->setText("Block10~14"); + } + + } +} + +void MF_trailerDecoderDialog::setTableItem(QTableWidget* widget, int row, int column, AccessType accessType) +{ + if(widget->item(row, column) == nullptr) + widget->setItem(row, column, new QTableWidgetItem()); + QString text; + if(accessType == ACC_NEVER) + { + text = "X"; + } + else if(accessType == ACC_KEY_A) + { + text = "KeyA"; + } + else if(accessType == ACC_KEY_B) + { + text = "KeyB"; + } + else if(accessType == ACC_KEY_AB) + { + text = "KeyA+B"; + } + widget->item(row, column)->setText(text); +} diff --git a/ui/mf_trailerdecoderdialog.h b/ui/mf_trailerdecoderdialog.h new file mode 100644 index 0000000..5478cbd --- /dev/null +++ b/ui/mf_trailerdecoderdialog.h @@ -0,0 +1,75 @@ +#ifndef MF_TRAILERDECODERDIALOG_H +#define MF_TRAILERDECODERDIALOG_H + +#include +#include +#include +#include +#include + +namespace Ui +{ +class MF_trailerDecoderDialog; +} + +class MF_trailerDecoderDialog : public QDialog +{ + Q_OBJECT + +public: + explicit MF_trailerDecoderDialog(QWidget *parent = nullptr); + ~MF_trailerDecoderDialog(); + enum AccessType + { + ACC_NEVER = 0, + ACC_KEY_A = 1, + ACC_KEY_B = 2, + ACC_KEY_AB = 3, + }; + +private slots: + + void on_accessBitsEdit_textEdited(const QString &arg1); + + void on_blockSizeChanged(int id, bool st); +private: + Ui::MF_trailerDecoderDialog *ui; + QRegularExpressionValidator* validator; + QButtonGroup* sizeGroup; + void setTableItem(QTableWidget *widget, int row, int column, AccessType accessType); + AccessType dataCondition[8][4] = + { + {ACC_KEY_AB, ACC_KEY_AB, ACC_KEY_AB, ACC_KEY_AB}, + {ACC_KEY_AB, ACC_NEVER, ACC_NEVER, ACC_NEVER}, + {ACC_KEY_AB, ACC_KEY_B, ACC_NEVER, ACC_NEVER}, + {ACC_KEY_AB, ACC_KEY_B, ACC_KEY_B, ACC_KEY_AB}, + {ACC_KEY_AB, ACC_NEVER, ACC_NEVER, ACC_KEY_AB}, + {ACC_KEY_B, ACC_KEY_B, ACC_NEVER, ACC_NEVER}, + {ACC_KEY_B, ACC_NEVER, ACC_NEVER, ACC_NEVER}, + {ACC_NEVER, ACC_NEVER, ACC_NEVER, ACC_NEVER}, + }; + AccessType trailerReadCondition[8][3] = + { + {ACC_NEVER, ACC_KEY_A, ACC_KEY_A}, + {ACC_NEVER, ACC_KEY_A, ACC_KEY_A}, + {ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, + {ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, + {ACC_NEVER, ACC_KEY_A, ACC_KEY_A}, + {ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, + {ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, + {ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, + }; + AccessType trailerWriteCondition[8][3] = + { + {ACC_KEY_A, ACC_NEVER, ACC_KEY_A}, + {ACC_NEVER, ACC_NEVER, ACC_NEVER}, + {ACC_KEY_B, ACC_NEVER, ACC_KEY_B}, + {ACC_NEVER, ACC_NEVER, ACC_NEVER}, + {ACC_KEY_A, ACC_KEY_A, ACC_KEY_A}, + {ACC_KEY_B, ACC_KEY_B, ACC_KEY_B}, + {ACC_NEVER, ACC_KEY_B, ACC_NEVER}, + {ACC_NEVER, ACC_NEVER, ACC_NEVER}, + }; +}; + +#endif // MF_TRAILERDECODERDIALOG_H diff --git a/ui/mf_trailerdecoderdialog.ui b/ui/mf_trailerdecoderdialog.ui new file mode 100644 index 0000000..afcc957 --- /dev/null +++ b/ui/mf_trailerdecoderdialog.ui @@ -0,0 +1,228 @@ + + + MF_trailerDecoderDialog + + + + 0 + 0 + 531 + 436 + + + + Dialog + + + + + + Trailer Data:(Input the Access Bits, like "FF 07 80 69" or "FF 07 80") + + + + + + + + + + + + + + + + + + + + + + + Blocks + + + + + + 4 + + + true + + + + + + + 16 + + + + + + + + + + + + Data Block Permission: + + + + + + + + 0 + 4 + + + + QAbstractItemView::NoEditTriggers + + + + Block0 + + + + + Block1 + + + + + Block2 + + + + + Read + + + + + Write + + + + + Increase + + + + + Decrease/Transfer/Restore + + + + + + + + Trailer Block Permission: + + + + + + + + 0 + 3 + + + + QAbstractItemView::NoEditTriggers + + + + Read + + + + + Write + + + + + KeyA + + + + + Access Bits + + + + + KeyB + + + + + + + + + + Reference: +MF1S70YYX_V1 Product data sheet +Rev. 3.2 — 23 November 2017 + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + MF_trailerDecoderDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + MF_trailerDecoderDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +