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