|
|
@ -1,7 +1,6 @@
|
|
|
|
#include "mifare.h"
|
|
|
|
#include "mifare.h"
|
|
|
|
|
|
|
|
|
|
|
|
Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent)
|
|
|
|
Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent): QObject(parent)
|
|
|
|
: QObject(parent)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
this->parent = parent;
|
|
|
|
this->parent = parent;
|
|
|
|
util = addr;
|
|
|
|
util = addr;
|
|
|
@ -19,17 +18,16 @@ Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent)
|
|
|
|
|
|
|
|
|
|
|
|
QString Mifare::info(bool isRequiringOutput)
|
|
|
|
QString Mifare::info(bool isRequiringOutput)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (isRequiringOutput)
|
|
|
|
if(isRequiringOutput)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString result = util->execCMDWithOutput("hf 14a info", 500);
|
|
|
|
QString result = util->execCMDWithOutput("hf 14a info", 500);
|
|
|
|
qDebug() << result
|
|
|
|
qDebug() << result << result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0);
|
|
|
|
<< result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0);
|
|
|
|
|
|
|
|
result.replace("UID :", "|");
|
|
|
|
result.replace("UID :", "|");
|
|
|
|
result.replace("ATQA :", "|");
|
|
|
|
result.replace("ATQA :", "|");
|
|
|
|
result.replace("SAK :", "|");
|
|
|
|
result.replace("SAK :", "|");
|
|
|
|
result.replace("TYPE :", "|");
|
|
|
|
result.replace("TYPE :", "|");
|
|
|
|
QStringList lis = result.split("|");
|
|
|
|
QStringList lis = result.split("|");
|
|
|
|
if (lis.length() > 4)
|
|
|
|
if(lis.length() > 4)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
qDebug() << lis[1] + lis[2] + lis[3];
|
|
|
|
qDebug() << lis[1] + lis[2] + lis[3];
|
|
|
|
return lis[1] + lis[2] + lis[3];
|
|
|
|
return lis[1] + lis[2] + lis[3];
|
|
|
@ -48,13 +46,15 @@ QString Mifare::info(bool isRequiringOutput)
|
|
|
|
void Mifare::chk()
|
|
|
|
void Mifare::chk()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
"hf mf chk *" + QString::number(cardType.type) + " ?",
|
|
|
|
"hf mf chk *"
|
|
|
|
|
|
|
|
+ QString::number(cardType.type)
|
|
|
|
|
|
|
|
+ " ?",
|
|
|
|
1000 + cardType.type * 1000);
|
|
|
|
1000 + cardType.type * 1000);
|
|
|
|
qDebug() << result;
|
|
|
|
qDebug() << result;
|
|
|
|
|
|
|
|
|
|
|
|
int offset = 0;
|
|
|
|
int offset = 0;
|
|
|
|
QString tmp, tmp2;
|
|
|
|
QString tmp, tmp2;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
offset = chkKeyPattern->indexIn(result, offset);
|
|
|
|
offset = chkKeyPattern->indexIn(result, offset);
|
|
|
|
// offset = result.indexOf(*chkKeyPattern, offset);
|
|
|
|
// offset = result.indexOf(*chkKeyPattern, offset);
|
|
|
@ -62,10 +62,10 @@ void Mifare::chk()
|
|
|
|
offset += 39;
|
|
|
|
offset += 39;
|
|
|
|
qDebug() << tmp << offset;
|
|
|
|
qDebug() << tmp << offset;
|
|
|
|
tmp2 = tmp.mid(7, 12).trimmed();
|
|
|
|
tmp2 = tmp.mid(7, 12).trimmed();
|
|
|
|
if (tmp2 != "?")
|
|
|
|
if(tmp2 != "?")
|
|
|
|
keyAList->replace(i, tmp2);
|
|
|
|
keyAList->replace(i, tmp2);
|
|
|
|
tmp2 = tmp.mid(24, 12).trimmed();
|
|
|
|
tmp2 = tmp.mid(24, 12).trimmed();
|
|
|
|
if (tmp2 != "?")
|
|
|
|
if(tmp2 != "?")
|
|
|
|
keyBList->replace(i, tmp2);
|
|
|
|
keyBList->replace(i, tmp2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
data_syncWithKeyWidget();
|
|
|
|
data_syncWithKeyWidget();
|
|
|
@ -74,19 +74,21 @@ void Mifare::chk()
|
|
|
|
void Mifare::nested()
|
|
|
|
void Mifare::nested()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
"hf mf nested " + QString::number(cardType.type) + " *");
|
|
|
|
"hf mf nested "
|
|
|
|
|
|
|
|
+ QString::number(cardType.type)
|
|
|
|
|
|
|
|
+ " *");
|
|
|
|
|
|
|
|
|
|
|
|
int offset = 0;
|
|
|
|
int offset = 0;
|
|
|
|
QString tmp;
|
|
|
|
QString tmp;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
offset = nestedKeyPattern->indexIn(result, offset);
|
|
|
|
offset = nestedKeyPattern->indexIn(result, offset);
|
|
|
|
// offset = result.indexOf(*nestedKeyPattern, offset);
|
|
|
|
// offset = result.indexOf(*nestedKeyPattern, offset);
|
|
|
|
tmp = result.mid(offset, 47).toUpper();
|
|
|
|
tmp = result.mid(offset, 47).toUpper();
|
|
|
|
offset += 47;
|
|
|
|
offset += 47;
|
|
|
|
if (tmp.at(23) == '1')
|
|
|
|
if(tmp.at(23) == '1')
|
|
|
|
keyAList->replace(i, tmp.mid(7, 12).trimmed());
|
|
|
|
keyAList->replace(i, tmp.mid(7, 12).trimmed());
|
|
|
|
if (tmp.at(44) == '1')
|
|
|
|
if(tmp.at(44) == '1')
|
|
|
|
keyBList->replace(i, tmp.mid(28, 12).trimmed());
|
|
|
|
keyBList->replace(i, tmp.mid(28, 12).trimmed());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
data_syncWithKeyWidget();
|
|
|
|
data_syncWithKeyWidget();
|
|
|
@ -96,7 +98,7 @@ void Mifare::hardnested()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
MF_Attack_hardnestedDialog dialog(cardType.blocks);
|
|
|
|
MF_Attack_hardnestedDialog dialog(cardType.blocks);
|
|
|
|
connect(&dialog, &MF_Attack_hardnestedDialog::sendCMD, util, &Util::execCMD);
|
|
|
|
connect(&dialog, &MF_Attack_hardnestedDialog::sendCMD, util, &Util::execCMD);
|
|
|
|
if (dialog.exec() == QDialog::Accepted)
|
|
|
|
if(dialog.exec() == QDialog::Accepted)
|
|
|
|
ui->funcTab->setCurrentIndex(1);
|
|
|
|
ui->funcTab->setCurrentIndex(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -117,29 +119,33 @@ void Mifare::read()
|
|
|
|
int waitTime = 300;
|
|
|
|
int waitTime = 300;
|
|
|
|
int currblk = ui->MF_RW_blockBox->currentText().toInt();
|
|
|
|
int currblk = ui->MF_RW_blockBox->currentText().toInt();
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
"hf mf rdbl " + QString::number(currblk) + " " +
|
|
|
|
"hf mf rdbl "
|
|
|
|
ui->MF_RW_keyTypeBox->currentText() + " " + ui->MF_RW_keyEdit->text(),
|
|
|
|
+ QString::number(currblk)
|
|
|
|
|
|
|
|
+ " "
|
|
|
|
|
|
|
|
+ ui->MF_RW_keyTypeBox->currentText()
|
|
|
|
|
|
|
|
+ " "
|
|
|
|
|
|
|
|
+ ui->MF_RW_keyEdit->text(),
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
if (result.indexOf("isOk:01") != -1)
|
|
|
|
if(result.indexOf("isOk:01") != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = result.mid(dataPattern->indexIn(result), 47).toUpper();
|
|
|
|
result = result.mid(dataPattern->indexIn(result), 47).toUpper();
|
|
|
|
if ((currblk < 128 && ((currblk + 1) % 4 == 0)) ||
|
|
|
|
if((currblk < 128 && ((currblk + 1) % 4 == 0)) || ((currblk + 1) % 8 == 0)) // process key block
|
|
|
|
((currblk + 1) % 8 == 0)) // process key block
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (ui->MF_RW_keyTypeBox->currentText() == "A")
|
|
|
|
if(ui->MF_RW_keyTypeBox->currentText() == "A")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
for(int i = 0; i < 6; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result =
|
|
|
|
result = result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2));
|
|
|
|
result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ui->MF_RW_dataEdit->setText(result);
|
|
|
|
ui->MF_RW_dataEdit->setText(result);
|
|
|
|
QString tmpKey = result.right(18).replace(" ", "");
|
|
|
|
QString tmpKey = result.right(18).replace(" ", "");
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
"hf mf rdbl " + ui->MF_RW_keyTypeBox->currentText() + " B " +
|
|
|
|
"hf mf rdbl "
|
|
|
|
tmpKey,
|
|
|
|
+ ui->MF_RW_keyTypeBox->currentText()
|
|
|
|
|
|
|
|
+ " B "
|
|
|
|
|
|
|
|
+ tmpKey,
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
if (result.indexOf("isOk:01") == -1)
|
|
|
|
if(result.indexOf("isOk:01") == -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = ui->MF_RW_dataEdit->text();
|
|
|
|
result = ui->MF_RW_dataEdit->text();
|
|
|
|
result = result.replace(30, 17, "?? ?? ?? ?? ?? ??");
|
|
|
|
result = result.replace(30, 17, "?? ?? ?? ?? ?? ??");
|
|
|
@ -148,10 +154,12 @@ void Mifare::read()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
for(int i = 0; i < 6; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = result.replace(30 + i * 3, 2,
|
|
|
|
result = result.replace(
|
|
|
|
ui->MF_RW_keyEdit->text().mid(i * 2, 2));
|
|
|
|
30 + i * 3,
|
|
|
|
|
|
|
|
2,
|
|
|
|
|
|
|
|
ui->MF_RW_keyEdit->text().mid(i * 2, 2));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? ");
|
|
|
|
result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? ");
|
|
|
|
ui->MF_RW_dataEdit->setText(result);
|
|
|
|
ui->MF_RW_dataEdit->setText(result);
|
|
|
@ -173,24 +181,27 @@ void Mifare::readAll()
|
|
|
|
|
|
|
|
|
|
|
|
QString tmp;
|
|
|
|
QString tmp;
|
|
|
|
int offset = 0;
|
|
|
|
int offset = 0;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = "";
|
|
|
|
result = "";
|
|
|
|
isKeyAValid = false;
|
|
|
|
isKeyAValid = false;
|
|
|
|
isKeyBValid = false;
|
|
|
|
isKeyBValid = false;
|
|
|
|
|
|
|
|
|
|
|
|
// check keys and read the first block of each sector
|
|
|
|
// check keys and read the first block of each sector
|
|
|
|
if (data_isKeyValid(keyAList->at(i)))
|
|
|
|
if(data_isKeyValid(keyAList->at(i)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = util->execCMDWithOutput("hf mf rdsc " + QString::number(i) +
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
" A " + keyAList->at(i),
|
|
|
|
"hf mf rdsc "
|
|
|
|
waitTime);
|
|
|
|
+ QString::number(i)
|
|
|
|
|
|
|
|
+ " A "
|
|
|
|
|
|
|
|
+ keyAList->at(i),
|
|
|
|
|
|
|
|
waitTime);
|
|
|
|
qDebug() << result;
|
|
|
|
qDebug() << result;
|
|
|
|
offset = result.indexOf("isOk:01");
|
|
|
|
offset = result.indexOf("isOk:01");
|
|
|
|
if (offset != -1)
|
|
|
|
if(offset != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
isKeyAValid = true;
|
|
|
|
isKeyAValid = true;
|
|
|
|
for (int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
for(int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
offset = dataPattern->indexIn(result, offset);
|
|
|
|
offset = dataPattern->indexIn(result, offset);
|
|
|
|
// offset = result.indexOf(*dataPattern, offset);
|
|
|
|
// offset = result.indexOf(*dataPattern, offset);
|
|
|
@ -203,17 +214,20 @@ void Mifare::readAll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (data_isKeyValid(keyBList->at(i)))
|
|
|
|
if(data_isKeyValid(keyBList->at(i)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = util->execCMDWithOutput("hf mf rdsc " + QString::number(i) +
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
" B " + keyBList->at(i),
|
|
|
|
"hf mf rdsc "
|
|
|
|
waitTime);
|
|
|
|
+ QString::number(i)
|
|
|
|
|
|
|
|
+ " B "
|
|
|
|
|
|
|
|
+ keyBList->at(i),
|
|
|
|
|
|
|
|
waitTime);
|
|
|
|
qDebug() << result;
|
|
|
|
qDebug() << result;
|
|
|
|
offset = result.indexOf("isOk:01");
|
|
|
|
offset = result.indexOf("isOk:01");
|
|
|
|
if (offset != -1)
|
|
|
|
if(offset != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
isKeyBValid = true;
|
|
|
|
isKeyBValid = true;
|
|
|
|
for (int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
for(int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
offset = dataPattern->indexIn(result, offset);
|
|
|
|
offset = dataPattern->indexIn(result, offset);
|
|
|
|
// offset = result.indexOf(*dataPattern, offset);
|
|
|
|
// offset = result.indexOf(*dataPattern, offset);
|
|
|
@ -227,7 +241,7 @@ void Mifare::readAll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (isKeyAValid || isKeyBValid)
|
|
|
|
if(isKeyAValid || isKeyBValid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
// fill the MF_dataWidget with the known valid key
|
|
|
|
// fill the MF_dataWidget with the known valid key
|
|
|
@ -239,7 +253,7 @@ void Mifare::readAll()
|
|
|
|
// the structure is not symmetric, since you cannot get KeyA from output
|
|
|
|
// the structure is not symmetric, since you cannot get KeyA from output
|
|
|
|
// this program will only process the provided KeyA(in MF_keyWidget)
|
|
|
|
// this program will only process the provided KeyA(in MF_keyWidget)
|
|
|
|
result = dataList->at(cardType.blks[i] + cardType.blk[i] - 1);
|
|
|
|
result = dataList->at(cardType.blks[i] + cardType.blk[i] - 1);
|
|
|
|
if (isKeyAValid)
|
|
|
|
if(isKeyAValid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result.replace(0, 12, keyAList->at(i));
|
|
|
|
result.replace(0, 12, keyAList->at(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -249,7 +263,7 @@ void Mifare::readAll()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result);
|
|
|
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result);
|
|
|
|
|
|
|
|
|
|
|
|
if (isKeyBValid)
|
|
|
|
if(isKeyBValid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result.replace(20, 12, keyBList->at(i));
|
|
|
|
result.replace(20, 12, keyBList->at(i));
|
|
|
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result);
|
|
|
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result);
|
|
|
@ -260,11 +274,12 @@ void Mifare::readAll()
|
|
|
|
QString tmpKey =
|
|
|
|
QString tmpKey =
|
|
|
|
dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12);
|
|
|
|
dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12);
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
"hf mf rdbl " +
|
|
|
|
"hf mf rdbl "
|
|
|
|
QString::number(cardType.blks[i] + cardType.blk[i] - 1) +
|
|
|
|
+ QString::number(cardType.blks[i] + cardType.blk[i] - 1)
|
|
|
|
" B " + tmpKey,
|
|
|
|
+ " B "
|
|
|
|
|
|
|
|
+ tmpKey,
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
if (result.indexOf("isOk:01") != -1)
|
|
|
|
if(result.indexOf("isOk:01") != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
keyBList->replace(i, tmpKey);
|
|
|
|
keyBList->replace(i, tmpKey);
|
|
|
|
data_syncWithKeyWidget(false, i, false);
|
|
|
|
data_syncWithKeyWidget(false, i, false);
|
|
|
@ -290,7 +305,7 @@ void Mifare::write()
|
|
|
|
ui->MF_RW_keyEdit->text() + " " +
|
|
|
|
ui->MF_RW_keyEdit->text() + " " +
|
|
|
|
ui->MF_RW_dataEdit->text().replace(" ", ""),
|
|
|
|
ui->MF_RW_dataEdit->text().replace(" ", ""),
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
if (result.indexOf("isOk:01") != -1)
|
|
|
|
if(result.indexOf("isOk:01") != -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QMessageBox::information(parent, tr("Info"), tr("Success!"));
|
|
|
|
QMessageBox::information(parent, tr("Info"), tr("Success!"));
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -304,30 +319,35 @@ void Mifare::writeAll()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const int waitTime = 300;
|
|
|
|
const int waitTime = 300;
|
|
|
|
QString result;
|
|
|
|
QString result;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
for(int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = ""; // if the KeyA is invalid and the result is not empty, the
|
|
|
|
result = ""; // if the KeyA is invalid and the result is not empty, the
|
|
|
|
// KeyB will not be tested.
|
|
|
|
// KeyB will not be tested.
|
|
|
|
if (data_isDataValid(dataList->at(cardType.blks[i] + j)) !=
|
|
|
|
if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?'))
|
|
|
|
DATA_NOSPACE ||
|
|
|
|
|
|
|
|
dataList->at(cardType.blks[i] + j).contains('?'))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
if (data_isKeyValid(keyAList->at(i)))
|
|
|
|
if(data_isKeyValid(keyAList->at(i)))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
"hf mf wrbl " + QString::number(cardType.blks[i] + j) + " A " +
|
|
|
|
"hf mf wrbl " +
|
|
|
|
keyAList->at(i) + " " + dataList->at(cardType.blks[i] + j),
|
|
|
|
QString::number(cardType.blks[i] + j)
|
|
|
|
|
|
|
|
+ " A "
|
|
|
|
|
|
|
|
+ keyAList->at(i)
|
|
|
|
|
|
|
|
+ " "
|
|
|
|
|
|
|
|
+ dataList->at(cardType.blks[i] + j),
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qDebug() << i << j << result.indexOf("isOk:01")
|
|
|
|
qDebug() << i << j << result.indexOf("isOk:01") << data_isKeyValid(keyBList->at(i));
|
|
|
|
<< data_isKeyValid(keyBList->at(i));
|
|
|
|
if(result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i)))
|
|
|
|
if (result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i)))
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
"hf mf wrbl " + QString::number(cardType.blks[i] + j) + " B " +
|
|
|
|
"hf mf wrbl "
|
|
|
|
keyBList->at(i) + " " + dataList->at(cardType.blks[i] + j),
|
|
|
|
+ QString::number(cardType.blks[i] + j)
|
|
|
|
|
|
|
|
+ " B "
|
|
|
|
|
|
|
|
+ keyBList->at(i)
|
|
|
|
|
|
|
|
+ " "
|
|
|
|
|
|
|
|
+ dataList->at(cardType.blks[i] + j),
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -339,8 +359,10 @@ void Mifare::readC()
|
|
|
|
int waitTime = 300;
|
|
|
|
int waitTime = 300;
|
|
|
|
int currblk = ui->MF_RW_blockBox->currentText().toInt();
|
|
|
|
int currblk = ui->MF_RW_blockBox->currentText().toInt();
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
"hf mf cgetblk " + QString::number(currblk), waitTime);
|
|
|
|
"hf mf cgetblk "
|
|
|
|
if (result.indexOf("No chinese") == -1)
|
|
|
|
+ QString::number(currblk),
|
|
|
|
|
|
|
|
waitTime);
|
|
|
|
|
|
|
|
if(result.indexOf("No chinese") == -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = result.mid(dataPattern->indexIn(result), 47).toUpper();
|
|
|
|
result = result.mid(dataPattern->indexIn(result), 47).toUpper();
|
|
|
|
ui->MF_RW_dataEdit->setText(result);
|
|
|
|
ui->MF_RW_dataEdit->setText(result);
|
|
|
@ -354,14 +376,17 @@ void Mifare::readAllC()
|
|
|
|
|
|
|
|
|
|
|
|
QString tmp;
|
|
|
|
QString tmp;
|
|
|
|
int offset = 0;
|
|
|
|
int offset = 0;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = util->execCMDWithOutput("hf mf cgetsc " + QString::number(i), waitTime);
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
|
|
|
|
"hf mf cgetsc "
|
|
|
|
|
|
|
|
+ QString::number(i),
|
|
|
|
|
|
|
|
waitTime);
|
|
|
|
qDebug() << result;
|
|
|
|
qDebug() << result;
|
|
|
|
if (result.indexOf("No chinese") == -1)
|
|
|
|
if(result.indexOf("No chinese") == -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
offset = 0;
|
|
|
|
offset = 0;
|
|
|
|
for (int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
for(int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
offset = dataPattern->indexIn(result, offset);
|
|
|
|
offset = dataPattern->indexIn(result, offset);
|
|
|
|
// offset = result.indexOf(*dataPattern, offset);
|
|
|
|
// offset = result.indexOf(*dataPattern, offset);
|
|
|
@ -372,10 +397,8 @@ void Mifare::readAllC()
|
|
|
|
dataList->replace(cardType.blks[i] + j, tmp);
|
|
|
|
dataList->replace(cardType.blks[i] + j, tmp);
|
|
|
|
data_syncWithDataWidget(false, cardType.blks[i] + j);
|
|
|
|
data_syncWithDataWidget(false, cardType.blks[i] + j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
keyAList->replace(
|
|
|
|
keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12));
|
|
|
|
i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12));
|
|
|
|
keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12));
|
|
|
|
keyBList->replace(
|
|
|
|
|
|
|
|
i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12));
|
|
|
|
|
|
|
|
data_syncWithKeyWidget(false, i, true);
|
|
|
|
data_syncWithKeyWidget(false, i, true);
|
|
|
|
data_syncWithKeyWidget(false, i, false);
|
|
|
|
data_syncWithKeyWidget(false, i, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -386,10 +409,12 @@ void Mifare::writeC()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int waitTime = 150;
|
|
|
|
int waitTime = 150;
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
QString result = util->execCMDWithOutput(
|
|
|
|
"hf mf csetblk " + ui->MF_RW_blockBox->currentText() + " " +
|
|
|
|
"hf mf csetblk "
|
|
|
|
ui->MF_RW_dataEdit->text().replace(" ", ""),
|
|
|
|
+ ui->MF_RW_blockBox->currentText()
|
|
|
|
|
|
|
|
+ " "
|
|
|
|
|
|
|
|
+ ui->MF_RW_dataEdit->text().replace(" ", ""),
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
if (result.indexOf("No chinese") == -1)
|
|
|
|
if(result.indexOf("No chinese") == -1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QMessageBox::information(parent, tr("Info"), tr("Success!"));
|
|
|
|
QMessageBox::information(parent, tr("Info"), tr("Success!"));
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -403,17 +428,18 @@ void Mifare::writeAllC()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const int waitTime = 150;
|
|
|
|
const int waitTime = 150;
|
|
|
|
QString result;
|
|
|
|
QString result;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
for(int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = "";
|
|
|
|
result = "";
|
|
|
|
if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE ||
|
|
|
|
if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?'))
|
|
|
|
dataList->at(cardType.blks[i] + j).contains('?'))
|
|
|
|
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
"hf mf csetblk " + QString::number(cardType.blks[i] + j) + " " +
|
|
|
|
"hf mf csetblk "
|
|
|
|
dataList->at(cardType.blks[i] + j),
|
|
|
|
+ QString::number(cardType.blks[i] + j)
|
|
|
|
|
|
|
|
+ " "
|
|
|
|
|
|
|
|
+ dataList->at(cardType.blks[i] + j),
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -421,14 +447,17 @@ void Mifare::writeAllC()
|
|
|
|
|
|
|
|
|
|
|
|
void Mifare::wipeC()
|
|
|
|
void Mifare::wipeC()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
util->execCMD("hf mf cwipe " + QString::number(cardType.type) + " f");
|
|
|
|
util->execCMD(
|
|
|
|
|
|
|
|
"hf mf cwipe "
|
|
|
|
|
|
|
|
+ QString::number(cardType.type)
|
|
|
|
|
|
|
|
+ " f");
|
|
|
|
ui->funcTab->setCurrentIndex(1);
|
|
|
|
ui->funcTab->setCurrentIndex(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Mifare::setParameterC()
|
|
|
|
void Mifare::setParameterC()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString result = info(true);
|
|
|
|
QString result = info(true);
|
|
|
|
if (result == "")
|
|
|
|
if(result == "")
|
|
|
|
QMessageBox::information(parent, tr("Info"), tr("Failed to read card."));
|
|
|
|
QMessageBox::information(parent, tr("Info"), tr("Failed to read card."));
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -436,10 +465,9 @@ void Mifare::setParameterC()
|
|
|
|
lis[0].replace(" ", "");
|
|
|
|
lis[0].replace(" ", "");
|
|
|
|
lis[1].replace(" ", "");
|
|
|
|
lis[1].replace(" ", "");
|
|
|
|
lis[2].replace(" ", "");
|
|
|
|
lis[2].replace(" ", "");
|
|
|
|
MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(),
|
|
|
|
MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(), lis[2].mid(0, 2).toUpper());
|
|
|
|
lis[2].mid(0, 2).toUpper());
|
|
|
|
|
|
|
|
connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD);
|
|
|
|
connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD);
|
|
|
|
if (dialog.exec() == QDialog::Accepted)
|
|
|
|
if(dialog.exec() == QDialog::Accepted)
|
|
|
|
ui->funcTab->setCurrentIndex(1);
|
|
|
|
ui->funcTab->setCurrentIndex(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -450,8 +478,7 @@ void Mifare::lockC()
|
|
|
|
util->execCMD("hf 14a raw -pa 43");
|
|
|
|
util->execCMD("hf 14a raw -pa 43");
|
|
|
|
util->execCMD("hf 14a raw -pa E0 00 39 F7");
|
|
|
|
util->execCMD("hf 14a raw -pa E0 00 39 F7");
|
|
|
|
util->execCMD("hf 14a raw -pa E1 00 E1 EE");
|
|
|
|
util->execCMD("hf 14a raw -pa E1 00 E1 EE");
|
|
|
|
util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 "
|
|
|
|
util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 18 47");
|
|
|
|
" 00 00 00 08 18 47");
|
|
|
|
|
|
|
|
util->execCMD("hf 14a raw 52");
|
|
|
|
util->execCMD("hf 14a raw 52");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -459,15 +486,16 @@ void Mifare::writeAllE()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
const int waitTime = 200;
|
|
|
|
const int waitTime = 200;
|
|
|
|
QString result;
|
|
|
|
QString result;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
for(int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
result = "";
|
|
|
|
result = "";
|
|
|
|
if (data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?'))
|
|
|
|
if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?'))
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
"hf mf eset " + QString::number(cardType.blks[i] + j)
|
|
|
|
"hf mf eset "
|
|
|
|
|
|
|
|
+ QString::number(cardType.blks[i] + j)
|
|
|
|
+ " "
|
|
|
|
+ " "
|
|
|
|
+ dataList->at(cardType.blks[i] + j),
|
|
|
|
+ dataList->at(cardType.blks[i] + j),
|
|
|
|
waitTime);
|
|
|
|
waitTime);
|
|
|
@ -483,14 +511,17 @@ void Mifare::readAllE()
|
|
|
|
|
|
|
|
|
|
|
|
QString tmp;
|
|
|
|
QString tmp;
|
|
|
|
int offset = 0;
|
|
|
|
int offset = 0;
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
offset = 0;
|
|
|
|
offset = 0;
|
|
|
|
for (int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
for(int j = 0; j < cardType.blk[i]; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
qDebug() << "**********" ;
|
|
|
|
qDebug() << "**********" ;
|
|
|
|
result = util->execCMDWithOutput("hf mf eget " + QString::number(cardType.blks[i] + j), waitTime);
|
|
|
|
result = util->execCMDWithOutput(
|
|
|
|
|
|
|
|
"hf mf eget "
|
|
|
|
|
|
|
|
+ QString::number(cardType.blks[i] + j),
|
|
|
|
|
|
|
|
waitTime);
|
|
|
|
qDebug() << result ;
|
|
|
|
qDebug() << result ;
|
|
|
|
|
|
|
|
|
|
|
|
offset = dataPattern->indexIn(result);
|
|
|
|
offset = dataPattern->indexIn(result);
|
|
|
@ -534,15 +565,15 @@ void Mifare::restore()
|
|
|
|
void Mifare::data_syncWithDataWidget(bool syncAll, int block)
|
|
|
|
void Mifare::data_syncWithDataWidget(bool syncAll, int block)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString tmp;
|
|
|
|
QString tmp;
|
|
|
|
if (syncAll)
|
|
|
|
if(syncAll)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.blocks; i++)
|
|
|
|
for(int i = 0; i < cardType.blocks; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp = "";
|
|
|
|
tmp = "";
|
|
|
|
if (dataList->at(i) != "")
|
|
|
|
if(dataList->at(i) != "")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp += dataList->at(i).mid(0, 2);
|
|
|
|
tmp += dataList->at(i).mid(0, 2);
|
|
|
|
for (int j = 1; j < 16; j++)
|
|
|
|
for(int j = 1; j < 16; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp += " ";
|
|
|
|
tmp += " ";
|
|
|
|
tmp += dataList->at(i).mid(j * 2, 2);
|
|
|
|
tmp += dataList->at(i).mid(j * 2, 2);
|
|
|
@ -554,10 +585,10 @@ void Mifare::data_syncWithDataWidget(bool syncAll, int block)
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp = "";
|
|
|
|
tmp = "";
|
|
|
|
if (dataList->at(block) != "")
|
|
|
|
if(dataList->at(block) != "")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp += dataList->at(block).mid(0, 2);
|
|
|
|
tmp += dataList->at(block).mid(0, 2);
|
|
|
|
for (int j = 1; j < 16; j++)
|
|
|
|
for(int j = 1; j < 16; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp += " ";
|
|
|
|
tmp += " ";
|
|
|
|
tmp += dataList->at(block).mid(j * 2, 2);
|
|
|
|
tmp += dataList->at(block).mid(j * 2, 2);
|
|
|
@ -569,9 +600,9 @@ void Mifare::data_syncWithDataWidget(bool syncAll, int block)
|
|
|
|
|
|
|
|
|
|
|
|
void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA)
|
|
|
|
void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (syncAll)
|
|
|
|
if(syncAll)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ui->MF_keyWidget->item(i, 1)->setText(keyAList->at(i));
|
|
|
|
ui->MF_keyWidget->item(i, 1)->setText(keyAList->at(i));
|
|
|
|
ui->MF_keyWidget->item(i, 2)->setText(keyBList->at(i));
|
|
|
|
ui->MF_keyWidget->item(i, 2)->setText(keyBList->at(i));
|
|
|
@ -579,7 +610,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (isKeyA)
|
|
|
|
if(isKeyA)
|
|
|
|
ui->MF_keyWidget->item(sector, 1)->setText(keyAList->at(sector));
|
|
|
|
ui->MF_keyWidget->item(sector, 1)->setText(keyAList->at(sector));
|
|
|
|
else
|
|
|
|
else
|
|
|
|
ui->MF_keyWidget->item(sector, 2)->setText(keyBList->at(sector));
|
|
|
|
ui->MF_keyWidget->item(sector, 2)->setText(keyBList->at(sector));
|
|
|
@ -589,7 +620,7 @@ void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA)
|
|
|
|
void Mifare::data_clearData()
|
|
|
|
void Mifare::data_clearData()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
dataList->clear();
|
|
|
|
dataList->clear();
|
|
|
|
for (int i = 0; i < cardType.blocks; i++)
|
|
|
|
for(int i = 0; i < cardType.blocks; i++)
|
|
|
|
dataList->append("");
|
|
|
|
dataList->append("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -597,7 +628,7 @@ void Mifare::data_clearKey()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
keyAList->clear();
|
|
|
|
keyAList->clear();
|
|
|
|
keyBList->clear();
|
|
|
|
keyBList->clear();
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
keyAList->append("");
|
|
|
|
keyAList->append("");
|
|
|
|
keyBList->append("");
|
|
|
|
keyBList->append("");
|
|
|
@ -606,11 +637,11 @@ void Mifare::data_clearKey()
|
|
|
|
|
|
|
|
|
|
|
|
bool Mifare::data_isKeyValid(const QString &key)
|
|
|
|
bool Mifare::data_isKeyValid(const QString &key)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (key.length() != 12)
|
|
|
|
if(key.length() != 12)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
for (int i = 0; i < 12; i++)
|
|
|
|
for(int i = 0; i < 12; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F')))
|
|
|
|
if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F')))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
@ -619,28 +650,28 @@ bool Mifare::data_isKeyValid(const QString &key)
|
|
|
|
Mifare::DataType
|
|
|
|
Mifare::DataType
|
|
|
|
Mifare::data_isDataValid(QString data) // "?" will not been processd there
|
|
|
|
Mifare::data_isDataValid(QString data) // "?" will not been processd there
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (data.length() == 47)
|
|
|
|
if(data.length() == 47)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 47; i++)
|
|
|
|
for(int i = 0; i < 47; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (i % 3 != 0)
|
|
|
|
if(i % 3 != 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
|
|
|
|
if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
|
|
|
|
return DATA_INVALID;
|
|
|
|
return DATA_INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (data[i] != ' ')
|
|
|
|
if(data[i] != ' ')
|
|
|
|
return DATA_INVALID;
|
|
|
|
return DATA_INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return DATA_WITHSPACE;
|
|
|
|
return DATA_WITHSPACE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (data.length() == 32)
|
|
|
|
else if(data.length() == 32)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 32; i++)
|
|
|
|
for(int i = 0; i < 32; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
|
|
|
|
if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
|
|
|
|
return DATA_INVALID;
|
|
|
|
return DATA_INVALID;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return DATA_NOSPACE;
|
|
|
|
return DATA_NOSPACE;
|
|
|
@ -656,15 +687,15 @@ Mifare::CardType Mifare::getCardType()
|
|
|
|
|
|
|
|
|
|
|
|
void Mifare::setCardType(int type)
|
|
|
|
void Mifare::setCardType(int type)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (type == 0 || type == 1 || type == 2 || type == 4)
|
|
|
|
if(type == 0 || type == 1 || type == 2 || type == 4)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (type == 0)
|
|
|
|
if(type == 0)
|
|
|
|
cardType = card_mini;
|
|
|
|
cardType = card_mini;
|
|
|
|
else if (type == 1)
|
|
|
|
else if(type == 1)
|
|
|
|
cardType = card_1k;
|
|
|
|
cardType = card_1k;
|
|
|
|
else if (type == 2)
|
|
|
|
else if(type == 2)
|
|
|
|
cardType = card_2k;
|
|
|
|
cardType = card_2k;
|
|
|
|
else if (type == 4)
|
|
|
|
else if(type == 4)
|
|
|
|
cardType = card_4k;
|
|
|
|
cardType = card_4k;
|
|
|
|
data_clearKey();
|
|
|
|
data_clearKey();
|
|
|
|
data_clearData();
|
|
|
|
data_clearData();
|
|
|
@ -674,25 +705,25 @@ void Mifare::setCardType(int type)
|
|
|
|
bool Mifare::data_loadDataFile(const QString &filename)
|
|
|
|
bool Mifare::data_loadDataFile(const QString &filename)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QFile file(filename, this);
|
|
|
|
QFile file(filename, this);
|
|
|
|
if (file.open(QIODevice::ReadOnly))
|
|
|
|
if(file.open(QIODevice::ReadOnly))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QByteArray buff;
|
|
|
|
QByteArray buff;
|
|
|
|
buff = file.read(10000);
|
|
|
|
buff = file.read(10000);
|
|
|
|
bool isBin = false;
|
|
|
|
bool isBin = false;
|
|
|
|
for (int i = 0; i < cardType.blocks * 16; i++) // Detect the file type
|
|
|
|
for(int i = 0; i < cardType.blocks * 16; i++) // Detect the file type
|
|
|
|
{
|
|
|
|
{
|
|
|
|
// qDebug() << (unsigned char)buff[i];
|
|
|
|
// qDebug() << (unsigned char)buff[i];
|
|
|
|
if (!((buff[i] >= 'A' && buff[i] <= 'F') || (buff[i] >= 'a' && buff[i] <= 'f') || (buff[i] >= '0' && buff[i] <= '9') || buff[i] == '\n' || buff[i] == '\r'))
|
|
|
|
if(!((buff[i] >= 'A' && buff[i] <= 'F') || (buff[i] >= 'a' && buff[i] <= 'f') || (buff[i] >= '0' && buff[i] <= '9') || buff[i] == '\n' || buff[i] == '\r'))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
isBin = true;
|
|
|
|
isBin = true;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isBin)
|
|
|
|
if(isBin)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (file.size() < cardType.blocks * 16)
|
|
|
|
if(file.size() < cardType.blocks * 16)
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
for (int i = 0; i < cardType.blocks; i++)
|
|
|
|
for(int i = 0; i < cardType.blocks; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString tmp = bin2text(buff, i, 16);
|
|
|
|
QString tmp = bin2text(buff, i, 16);
|
|
|
|
dataList->replace(i, tmp.toUpper());
|
|
|
|
dataList->replace(i, tmp.toUpper());
|
|
|
@ -702,7 +733,7 @@ bool Mifare::data_loadDataFile(const QString &filename)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString tmp = buff.left(cardType.blocks * 34);
|
|
|
|
QString tmp = buff.left(cardType.blocks * 34);
|
|
|
|
QStringList tmpList = tmp.split("\r\n");
|
|
|
|
QStringList tmpList = tmp.split("\r\n");
|
|
|
|
for (int i = 0; i < cardType.blocks; i++)
|
|
|
|
for(int i = 0; i < cardType.blocks; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
dataList->replace(i, tmpList[i].toUpper());
|
|
|
|
dataList->replace(i, tmpList[i].toUpper());
|
|
|
|
qDebug() << tmpList[i];
|
|
|
|
qDebug() << tmpList[i];
|
|
|
@ -721,14 +752,14 @@ 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);
|
|
|
|
QFile file(filename, this);
|
|
|
|
if (file.open(QIODevice::ReadOnly))
|
|
|
|
if(file.open(QIODevice::ReadOnly))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QByteArray buff;
|
|
|
|
QByteArray buff;
|
|
|
|
buff = file.read(10000);
|
|
|
|
buff = file.read(10000);
|
|
|
|
bool isKey = file.size() <= cardType.sectors * 14;
|
|
|
|
bool isKey = file.size() <= cardType.sectors * 14;
|
|
|
|
if (isKey)
|
|
|
|
if(isKey)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString tmp = bin2text(buff, i, 12);
|
|
|
|
QString tmp = bin2text(buff, i, 12);
|
|
|
|
keyAList->replace(i, tmp.left(12).toUpper());
|
|
|
|
keyAList->replace(i, tmp.left(12).toUpper());
|
|
|
@ -737,7 +768,7 @@ bool Mifare::data_loadKeyFile(const QString &filename)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int blk = cardType.blks[i] + cardType.blk[i] - 1;
|
|
|
|
int blk = cardType.blks[i] + cardType.blk[i] - 1;
|
|
|
|
QString tmp = bin2text(buff, blk, 16);
|
|
|
|
QString tmp = bin2text(buff, blk, 16);
|
|
|
@ -762,7 +793,7 @@ QString Mifare::bin2text(const QByteArray &buff, int i, int length)
|
|
|
|
char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
|
|
|
char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
|
|
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
|
|
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
|
|
|
};
|
|
|
|
};
|
|
|
|
for (int j = 0; j < length; j++)
|
|
|
|
for(int j = 0; j < length; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
LByte = map[(unsigned char)buff[i * length + j] >> 4];
|
|
|
|
LByte = map[(unsigned char)buff[i * length + j] >> 4];
|
|
|
|
RByte = map[(unsigned char)buff[i * length + j] & 0xF];
|
|
|
|
RByte = map[(unsigned char)buff[i * length + j] & 0xF];
|
|
|
@ -776,23 +807,23 @@ QString Mifare::bin2text(const QByteArray &buff, int i, int length)
|
|
|
|
bool Mifare::data_saveDataFile(const QString &filename, bool isBin)
|
|
|
|
bool Mifare::data_saveDataFile(const QString &filename, bool isBin)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QFile file(filename, this);
|
|
|
|
QFile file(filename, this);
|
|
|
|
if (file.open(QIODevice::WriteOnly))
|
|
|
|
if(file.open(QIODevice::WriteOnly))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QByteArray buff;
|
|
|
|
QByteArray buff;
|
|
|
|
QChar tmp;
|
|
|
|
QChar tmp;
|
|
|
|
if (isBin)
|
|
|
|
if(isBin)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.blocks; i++)
|
|
|
|
for(int i = 0; i < cardType.blocks; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 16; j++)
|
|
|
|
for(int j = 0; j < 16; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned char Byt[2];
|
|
|
|
unsigned char Byt[2];
|
|
|
|
for (int k = 0; k < 2; k++)
|
|
|
|
for(int k = 0; k < 2; k++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp = dataList->at(i).at(j * 2 + k).toUpper();
|
|
|
|
tmp = dataList->at(i).at(j * 2 + k).toUpper();
|
|
|
|
if (tmp >= '0' && tmp <= '9')
|
|
|
|
if(tmp >= '0' && tmp <= '9')
|
|
|
|
Byt[k] = tmp.toLatin1() - '0';
|
|
|
|
Byt[k] = tmp.toLatin1() - '0';
|
|
|
|
else if (tmp >= 'A' && tmp <= 'F')
|
|
|
|
else if(tmp >= 'A' && tmp <= 'F')
|
|
|
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
|
|
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buff += (Byt[0] << 4) | Byt[1];
|
|
|
|
buff += (Byt[0] << 4) | Byt[1];
|
|
|
@ -801,7 +832,7 @@ bool Mifare::data_saveDataFile(const QString &filename, bool isBin)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.blocks; i++)
|
|
|
|
for(int i = 0; i < cardType.blocks; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
buff += dataList->at(i);
|
|
|
|
buff += dataList->at(i);
|
|
|
|
buff += "\r\n";
|
|
|
|
buff += "\r\n";
|
|
|
@ -820,36 +851,36 @@ 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);
|
|
|
|
QFile file(filename, this);
|
|
|
|
if (file.open(QIODevice::WriteOnly))
|
|
|
|
if(file.open(QIODevice::WriteOnly))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QByteArray buff;
|
|
|
|
QByteArray buff;
|
|
|
|
QChar tmp;
|
|
|
|
QChar tmp;
|
|
|
|
if (isBin)
|
|
|
|
if(isBin)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int j = 0; j < 6; j++)
|
|
|
|
for(int j = 0; j < 6; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned char Byt[2];
|
|
|
|
unsigned char Byt[2];
|
|
|
|
for (int k = 0; k < 2; k++)
|
|
|
|
for(int k = 0; k < 2; k++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp = keyAList->at(i).at(j * 2 + k).toUpper();
|
|
|
|
tmp = keyAList->at(i).at(j * 2 + k).toUpper();
|
|
|
|
if (tmp >= '0' && tmp <= '9')
|
|
|
|
if(tmp >= '0' && tmp <= '9')
|
|
|
|
Byt[k] = tmp.toLatin1() - '0';
|
|
|
|
Byt[k] = tmp.toLatin1() - '0';
|
|
|
|
else if (tmp >= 'A' && tmp <= 'F')
|
|
|
|
else if(tmp >= 'A' && tmp <= 'F')
|
|
|
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
|
|
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buff += (Byt[0] << 4) | Byt[1];
|
|
|
|
buff += (Byt[0] << 4) | Byt[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int j = 0; j < 6; j++)
|
|
|
|
for(int j = 0; j < 6; j++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
unsigned char Byt[2];
|
|
|
|
unsigned char Byt[2];
|
|
|
|
for (int k = 0; k < 2; k++)
|
|
|
|
for(int k = 0; k < 2; k++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
tmp = keyBList->at(i).at(j * 2 + k).toUpper();
|
|
|
|
tmp = keyBList->at(i).at(j * 2 + k).toUpper();
|
|
|
|
if (tmp >= '0' && tmp <= '9')
|
|
|
|
if(tmp >= '0' && tmp <= '9')
|
|
|
|
Byt[k] = tmp.toLatin1() - '0';
|
|
|
|
Byt[k] = tmp.toLatin1() - '0';
|
|
|
|
else if (tmp >= 'A' && tmp <= 'F')
|
|
|
|
else if(tmp >= 'A' && tmp <= 'F')
|
|
|
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
|
|
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
buff += (Byt[0] << 4) | Byt[1];
|
|
|
|
buff += (Byt[0] << 4) | Byt[1];
|
|
|
@ -871,20 +902,20 @@ bool Mifare::data_saveKeyFile(const QString &filename, bool isBin)
|
|
|
|
|
|
|
|
|
|
|
|
void Mifare::data_key2Data()
|
|
|
|
void Mifare::data_key2Data()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
QString tmp = "";
|
|
|
|
QString tmp = "";
|
|
|
|
if (data_isKeyValid(keyAList->at(i)))
|
|
|
|
if(data_isKeyValid(keyAList->at(i)))
|
|
|
|
tmp += keyAList->at(i);
|
|
|
|
tmp += keyAList->at(i);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
tmp += "????????????";
|
|
|
|
tmp += "????????????";
|
|
|
|
|
|
|
|
|
|
|
|
if (dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "")
|
|
|
|
if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "")
|
|
|
|
tmp += "FF078069"; // default control bytes
|
|
|
|
tmp += "FF078069"; // default control bytes
|
|
|
|
else
|
|
|
|
else
|
|
|
|
tmp += dataList->at(cardType.blks[i] + cardType.blk[i] - 1).mid(12, 8);
|
|
|
|
tmp += dataList->at(cardType.blks[i] + cardType.blk[i] - 1).mid(12, 8);
|
|
|
|
|
|
|
|
|
|
|
|
if (data_isKeyValid(keyBList->at(i)))
|
|
|
|
if(data_isKeyValid(keyBList->at(i)))
|
|
|
|
tmp += keyBList->at(i);
|
|
|
|
tmp += keyBList->at(i);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
tmp += "????????????";
|
|
|
|
tmp += "????????????";
|
|
|
@ -896,19 +927,17 @@ void Mifare::data_key2Data()
|
|
|
|
|
|
|
|
|
|
|
|
void Mifare::data_data2Key()
|
|
|
|
void Mifare::data_data2Key()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (int i = 0; i < cardType.sectors; i++)
|
|
|
|
for(int i = 0; i < cardType.sectors; i++)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "")
|
|
|
|
if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "")
|
|
|
|
{
|
|
|
|
{
|
|
|
|
keyAList->replace(i, "????????????");
|
|
|
|
keyAList->replace(i, "????????????");
|
|
|
|
keyBList->replace(i, "????????????");
|
|
|
|
keyBList->replace(i, "????????????");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
keyAList->replace(
|
|
|
|
keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12));
|
|
|
|
i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12));
|
|
|
|
keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12));
|
|
|
|
keyBList->replace(
|
|
|
|
|
|
|
|
i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
data_syncWithKeyWidget();
|
|
|
|
data_syncWithKeyWidget();
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -921,7 +950,7 @@ void Mifare::data_setData(int block, const QString &data)
|
|
|
|
|
|
|
|
|
|
|
|
void Mifare::data_setKey(int sector, bool isKeyA, const QString &key)
|
|
|
|
void Mifare::data_setKey(int sector, bool isKeyA, const QString &key)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (isKeyA)
|
|
|
|
if(isKeyA)
|
|
|
|
keyAList->replace(sector, key);
|
|
|
|
keyAList->replace(sector, key);
|
|
|
|
else
|
|
|
|
else
|
|
|
|
keyBList->replace(sector, key);
|
|
|
|
keyBList->replace(sector, key);
|
|
|
|