diff --git a/module/mifare.cpp b/module/mifare.cpp index de253ed..de6c5cc 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -108,18 +108,32 @@ void Mifare::sniff() ui->funcTab->setCurrentIndex(1); } +void Mifare::snoop() +{ + util->execCMD("hf 14a snoop"); + ui->funcTab->setCurrentIndex(1); +} + void Mifare::list() { util->execCMD("hf list mf"); ui->funcTab->setCurrentIndex(1); } -QString Mifare::_readblk(int blockId, KeyType keyType, QString& key, int waitTime) +QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, int waitTime) { QString data; QString result; + bool isKeyBlock = (blockId < 128 && ((blockId + 1) % 4 == 0)) || ((blockId + 1) % 8 == 0); + + if(!data_isKeyValid(key)) + { + return ""; + } + if(util->getClientType() == Util::OFFICIAL) { + // use the given key type to read the target block result = util->execCMDWithOutput( "hf mf rdbl " + QString::number(blockId) @@ -131,111 +145,106 @@ QString Mifare::_readblk(int blockId, KeyType keyType, QString& key, int waitTim if(result.indexOf("isOk:01") != -1) { result = result.mid(dataPattern->indexIn(result), 47).toUpper(); - if((blockId < 128 && ((blockId + 1) % 4 == 0)) || ((blockId + 1) % 8 == 0)) // process key block - { - if(keyType == KEY_A) - { - for(int i = 0; i < 6; i++) - { - result = result.replace(i * 3, 2, key.mid(i * 2, 2)); - } - data = result; - QString tmpKey = result.right(18).replace(" ", ""); - result = util->execCMDWithOutput( - "hf mf rdbl " - + QString::number(blockId) - + " B " - + tmpKey, - waitTime); - if(result.indexOf("isOk:01") == -1) - { - result = data; - result = result.replace(30, 17, "?? ?? ?? ?? ?? ??"); - data = result; - } - } - else - { - for(int i = 0; i < 6; i++) - { - result = result.replace( - 30 + i * 3, - 2, - key.mid(i * 2, 2)); - } - result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? "); - data = result; - } - } - else + + // when the target block is a key block and the given key type is keyA, try to check whether the keyB is valid + // if the given key type is keyB, it will never get the keyA from the key block + if(!isKeyBlock) { data = result; } - } - else - { - data = ""; - } - return data; - } -} - -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(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") + else if(isKeyBlock && keyType == KEY_A) { 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, key.mid(i * 2, 2)); } - ui->MF_RW_dataEdit->setText(result); + data = result; QString tmpKey = result.right(18).replace(" ", ""); result = util->execCMDWithOutput( "hf mf rdbl " - + ui->MF_RW_keyTypeBox->currentText() + + QString::number(blockId) + " B " + tmpKey, waitTime); if(result.indexOf("isOk:01") == -1) { - result = ui->MF_RW_dataEdit->text(); + result = data; result = result.replace(30, 17, "?? ?? ?? ?? ?? ??"); - ui->MF_RW_dataEdit->setText(result); + data = result; } } - else + else if(isKeyBlock && keyType == KEY_B) { - for(int i = 0; i < 6; i++) + for(int i = 0; i < 6; i++) // use the given keyB to replace revelant part of block data { result = result.replace( 30 + i * 3, 2, - ui->MF_RW_keyEdit->text().mid(i * 2, 2)); + key.mid(i * 2, 2)); } - result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? "); - ui->MF_RW_dataEdit->setText(result); + result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? "); // fill the keyA part with ? + data = result; } } else { - ui->MF_RW_dataEdit->setText(result); + data = ""; + } + } + return data.remove(" "); +} + +QStringList Mifare::_readsec(int sectorId, KeyType keyType, const QString& key, int waitTime) +{ + QStringList data; + QString result, tmp; + int offset = 0; + + if(!data_isKeyValid(key)) + { + return data; + } + + if(util->getClientType() == Util::OFFICIAL) + { + result = util->execCMDWithOutput( + "hf mf rdsc " + + QString::number(sectorId) + + " " + + (char)keyType + + " " + + key, + waitTime); + offset = result.indexOf("isOk:01"); + if(offset != -1) + { + for(int i = 0; i < cardType.blk[sectorId]; i++) + { + offset = dataPattern->indexIn(result, offset); + tmp = result.mid(offset, 47).toUpper(); + offset += 47; + qDebug() << tmp; + tmp.remove(" "); + data.append(tmp); + } } } + return data; +} + +void Mifare::read() +{ + int blockId = ui->MF_RW_blockBox->currentText().toInt(); + Mifare::KeyType keyType = (Mifare::KeyType)(ui->MF_RW_keyTypeBox->currentData().toInt()); + QString result = _readblk(blockId, keyType, ui->MF_RW_keyEdit->text()); + if(result != "") + { + ui->MF_RW_dataEdit->setText(result); + } + else + { + ui->MF_RW_dataEdit->setText(tr("Failed")); + } } void Mifare::readAll() diff --git a/module/mifare.h b/module/mifare.h index ddc4011..d68bf9c 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -22,6 +22,7 @@ public: void nested(); void hardnested(); void sniff(); + void snoop(); void list(); void read(); void readAll(); @@ -119,6 +120,9 @@ public: void loadSniff(const QString& file); void saveSniff(const QString& file); void data_fillKeys(); + + QString _readblk(int blockId, KeyType keyType, const QString &key, int waitTime = 300); + QStringList _readsec(int sectorId, KeyType keyType, const QString &key, int waitTime = 300); public slots: signals: @@ -136,7 +140,8 @@ private: QRegExp* UIDPattern; QString bin2text(const QByteArray& buff, int start, int length); - QString _readblk(int blockId, KeyType keyType, QString &key, int waitTime); + //QString _readblk(int blockId, KeyType keyType, const QString &key, int waitTime = 300); + //QStringList _readsec(int sectorId, KeyType keyType, const QString &key, int waitTime = 300); }; #endif // MIFARE_H diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 4464ca8..4919334 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -202,25 +202,25 @@ void MainWindow::MF_onTypeChanged(int id, bool st) typeBtnGroup->blockSignals(false); } -void MainWindow::on_MF_checkAllBox_stateChanged(int arg1) +void MainWindow::on_MF_selectAllBox_stateChanged(int arg1) { ui->MF_dataWidget->blockSignals(true); - ui->MF_checkAllBox->blockSignals(true); + ui->MF_selectAllBox->blockSignals(true); if(arg1 == Qt::PartiallyChecked) { - ui->MF_checkAllBox->setTristate(false); - ui->MF_checkAllBox->setCheckState(Qt::Checked); + ui->MF_selectAllBox->setTristate(false); + ui->MF_selectAllBox->setCheckState(Qt::Checked); } for(int i = 0; i < mifare->cardType.blocks; i++) { - ui->MF_dataWidget->item(i, 1)->setCheckState(ui->MF_checkAllBox->checkState()); + ui->MF_dataWidget->item(i, 1)->setCheckState(ui->MF_selectAllBox->checkState()); } for(int i = 0; i < mifare->cardType.sectors; i++) { - ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(ui->MF_checkAllBox->checkState()); + ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(ui->MF_selectAllBox->checkState()); } ui->MF_dataWidget->blockSignals(false); - ui->MF_checkAllBox->blockSignals(false); + ui->MF_selectAllBox->blockSignals(false); } void MainWindow::on_MF_data2KeyButton_clicked() @@ -253,7 +253,7 @@ void MainWindow::on_MF_fontButton_clicked() void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item) { ui->MF_dataWidget->blockSignals(true); - ui->MF_checkAllBox->blockSignals(true); + ui->MF_selectAllBox->blockSignals(true); if(item->column() == 0) { int selectedSectors = 0; @@ -271,15 +271,15 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item) } if(selectedSectors == 0) { - ui->MF_checkAllBox->setCheckState(Qt::Unchecked); + ui->MF_selectAllBox->setCheckState(Qt::Unchecked); } else if(selectedSectors == mifare->cardType.sectors) { - ui->MF_checkAllBox->setCheckState(Qt::Checked); + ui->MF_selectAllBox->setCheckState(Qt::Checked); } else { - ui->MF_checkAllBox->setCheckState(Qt::PartiallyChecked); + ui->MF_selectAllBox->setCheckState(Qt::PartiallyChecked); } } else if(item->column() == 1) @@ -303,15 +303,15 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item) } if(selectedBlocks == 0) { - ui->MF_checkAllBox->setCheckState(Qt::Unchecked); + ui->MF_selectAllBox->setCheckState(Qt::Unchecked); } else if(selectedBlocks == mifare->cardType.blocks) { - ui->MF_checkAllBox->setCheckState(Qt::Checked); + ui->MF_selectAllBox->setCheckState(Qt::Checked); } else { - ui->MF_checkAllBox->setCheckState(Qt::PartiallyChecked); + ui->MF_selectAllBox->setCheckState(Qt::PartiallyChecked); } if(selectedSubBlocks == 0) { @@ -340,7 +340,7 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item) mifare->data_syncWithDataWidget(false, item->row()); } ui->MF_dataWidget->blockSignals(false); - ui->MF_checkAllBox->blockSignals(false); + ui->MF_selectAllBox->blockSignals(false); } void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item) @@ -659,6 +659,13 @@ void MainWindow::on_MF_Sniff_sniffButton_clicked() setState(true); } +void MainWindow::on_MF_Sniff_snoopButton_clicked() +{ + setState(false); + mifare->snoop(); + setState(true); +} + void MainWindow::on_MF_Sniff_listButton_clicked() { mifare->list(); @@ -673,7 +680,7 @@ void MainWindow::MF_widgetReset() ui->MF_dataWidget->setRowCount(blks); ui->MF_dataWidget->blockSignals(true); - ui->MF_checkAllBox->blockSignals(true); + ui->MF_selectAllBox->blockSignals(true); for(int i = 0; i < blks; i++) { @@ -692,10 +699,10 @@ void MainWindow::MF_widgetReset() setTableItem(ui->MF_dataWidget, mifare->cardType.blks[i], 0, QString::number(i)); ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Checked); } - ui->MF_checkAllBox->setCheckState(Qt::Checked); + ui->MF_selectAllBox->setCheckState(Qt::Checked); ui->MF_dataWidget->blockSignals(false); - ui->MF_checkAllBox->blockSignals(false); + ui->MF_selectAllBox->blockSignals(false); } // ************************************************ @@ -767,7 +774,8 @@ void MainWindow::uiInit() } settings->endGroup(); - + ui->MF_RW_keyTypeBox->addItem("A", Mifare::KEY_A); + ui->MF_RW_keyTypeBox->addItem("B", Mifare::KEY_B); on_Raw_CMDHistoryBox_stateChanged(Qt::Unchecked); on_PM3_refreshPortButton_clicked(); @@ -889,3 +897,10 @@ void MainWindow::on_GroupBox_clicked(bool checked) } // *********************************************** + + + +void MainWindow::on_testButton_clicked() +{ + mifare->_readsec(0, Mifare::KEY_A, "FFFFFFFFFFFF"); +} diff --git a/ui/mainwindow.h b/ui/mainwindow.h index 37d89b1..f3337b6 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -137,10 +137,14 @@ private slots: void on_GroupBox_clicked(bool checked); - void on_MF_checkAllBox_stateChanged(int arg1); + void on_MF_selectAllBox_stateChanged(int arg1); void on_MF_fillKeysButton_clicked(); + void on_MF_Sniff_snoopButton_clicked(); + + void on_testButton_clicked(); + private: Ui::MainWindow* ui; QButtonGroup* typeBtnGroup; diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index d678bdb..a32006c 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -183,9 +183,9 @@ - + - Check All + Select All false @@ -564,16 +564,6 @@ 16777215 - - - A - - - - - B - - @@ -585,6 +575,13 @@ + + + + test + + + @@ -827,6 +824,12 @@ + + + 40 + 0 + + Read All @@ -847,6 +850,12 @@ + + + 40 + 0 + + Simulate @@ -909,10 +918,29 @@ + + + + + 40 + 0 + + + + Snoop + + + + + + 40 + 0 + + - List Sniff Data + List Data