Support encode Access Bits(in the Trailer Decoder)

pull/4/head
wh201906 4 years ago
parent 46b3912e82
commit 7dfabb60e9

@ -295,19 +295,13 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, int w
{ {
data = dataPattern->match(result).captured().toUpper(); data = dataPattern->match(result).captured().toUpper();
data.remove(" "); data.remove(" ");
// when the target block is a key block and the given key type is keyA, try to check whether the keyB is valid // when the target block is a key block and the given key type is KeyA, try to check whether the KeyB is valid(by Access Bits)
// if the given key type is keyB, it will never get the keyA from the key block // if the given key type is KeyB, it will never get the KeyA from the key block
if(isKeyBlock && keyType == KEY_A) if(isKeyBlock && keyType == KEY_A)
{ {
data.replace(0, 12, key); data.replace(0, 12, key);
QString tmpKey = data.right(12); QList<quint8> ACBits = data_getACBits(data.mid(12, 8));
result = util->execCMDWithOutput( if(ACBits[3] == 2 || ACBits[3] == 3 || ACBits[3] == 5 || ACBits[3] == 6 || ACBits[3] == 7) // in these cases, the KeyB cannot be read by KeyA
"hf mf rdbl "
+ QString::number(blockId)
+ " B "
+ tmpKey,
waitTime);
if(result.indexOf("isOk:01") == -1)
{ {
data.replace(20, 12, "????????????"); data.replace(20, 12, "????????????");
} }
@ -852,8 +846,7 @@ bool Mifare::data_isKeyValid(const QString &key)
return true; return true;
} }
Mifare::DataType Mifare::DataType Mifare::data_isDataValid(const 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)
{ {
@ -1176,3 +1169,31 @@ void Mifare::data_fillKeys()
} }
data_syncWithKeyWidget(); data_syncWithKeyWidget();
} }
QList<quint8> Mifare::data_getACBits(const QString& text) //return empty QList if the text is invalid
{
QString input = text;
QList<quint8> result;
input.remove(" ");
if(input.length() < 6)
{
return result;
}
input = input.left(6);
quint32 val = input.toUInt(nullptr, 16);
quint8 halfBytes[6];
for(int i = 0; i < 6; i++)
{
halfBytes[i] = (val >> ((5 - i) * 4)) & 0xf;
}
qDebug() << val;
if((~halfBytes[0] & 0xf) == halfBytes[5] && (~halfBytes[1] & 0xf) == halfBytes[2] && (~halfBytes[3] & 0xf) == halfBytes[4])
{
for(int i = 0; i < 4; i++)
{
result.append((((halfBytes[4] >> i) & 1) << 2) | (((halfBytes[5] >> i) & 1) << 1) | (((halfBytes[2] >> i) & 1) << 0));
}
}
return result;
}

@ -72,8 +72,8 @@ public:
void data_clearData(); void data_clearData();
void data_clearKey(); void data_clearKey();
bool data_isKeyValid(const QString& key); static bool data_isKeyValid(const QString& key);
Mifare::DataType data_isDataValid(QString data); static Mifare::DataType data_isDataValid(const QString& data);
void data_syncWithDataWidget(bool syncAll = true, int block = 0); void data_syncWithDataWidget(bool syncAll = true, int block = 0);
void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, KeyType keyType = KEY_A); void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, KeyType keyType = KEY_A);
@ -107,6 +107,7 @@ public:
QString _readblk(int blockId, KeyType keyType, const QString &key, int waitTime = 300); QString _readblk(int blockId, KeyType keyType, const QString &key, int waitTime = 300);
QStringList _readsec(int sectorId, KeyType keyType, const QString &key, int waitTime = 300); QStringList _readsec(int sectorId, KeyType keyType, const QString &key, int waitTime = 300);
static QList<quint8> data_getACBits(const QString &text);
public slots: public slots:
signals: signals:

@ -15,6 +15,10 @@ MF_trailerDecoderDialog::MF_trailerDecoderDialog(QWidget *parent) :
sizeGroup->addButton(ui->size4Button, 4); sizeGroup->addButton(ui->size4Button, 4);
sizeGroup->addButton(ui->size16Button, 16); sizeGroup->addButton(ui->size16Button, 16);
connect(sizeGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MF_trailerDecoderDialog::on_blockSizeChanged); connect(sizeGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MF_trailerDecoderDialog::on_blockSizeChanged);
connect(ui->C0Box, &QSpinBox::textChanged, this, &MF_trailerDecoderDialog::on_boxChanged);
connect(ui->C1Box, &QSpinBox::textChanged, this, &MF_trailerDecoderDialog::on_boxChanged);
connect(ui->C2Box, &QSpinBox::textChanged, this, &MF_trailerDecoderDialog::on_boxChanged);
connect(ui->C3Box, &QSpinBox::textChanged, this, &MF_trailerDecoderDialog::on_boxChanged);
ui->dataBlockWidget->setRowCount(3); ui->dataBlockWidget->setRowCount(3);
ui->dataBlockWidget->setColumnCount(4); ui->dataBlockWidget->setColumnCount(4);
@ -26,37 +30,26 @@ MF_trailerDecoderDialog::~MF_trailerDecoderDialog()
{ {
delete ui; delete ui;
} }
void MF_trailerDecoderDialog::on_accessBitsEdit_textEdited(const QString &arg1) void MF_trailerDecoderDialog::on_accessBitsEdit_textChanged(const QString &arg1)
{ {
QString input = arg1; ui->C0Box->blockSignals(true);
input.remove(" "); ui->C1Box->blockSignals(true);
if(input.length() < 6) ui->C2Box->blockSignals(true);
{ ui->C3Box->blockSignals(true);
ui->isAccessBitsValidLabel->setText(""); QList<quint8> ACBits = Mifare::data_getACBits(arg1);
return; if(ACBits.size() == 0)
}
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->setStyleSheet("color:rgb(200, 0, 0)");
ui->isAccessBitsValidLabel->setText(tr("Invalid! It could make the whole sector blocked irreversibly!")); ui->isAccessBitsValidLabel->setText(tr("Invalid!\nIt could make the whole sector blocked irreversibly!"));
} }
else else
{ {
ui->C0Box->setValue(ACBits[0]);
ui->C1Box->setValue(ACBits[1]);
ui->C2Box->setValue(ACBits[2]);
ui->C3Box->setValue(ACBits[3]);
ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(0, 200, 0)"); ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(0, 200, 0)");
ui->isAccessBitsValidLabel->setText(tr("Valid")); 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; bool isKeyBReadable = ACBits[3] == 0 || ACBits[3] == 1 || ACBits[3] == 4;
for(int j = 0; j < 3; j++) for(int j = 0; j < 3; j++)
{ {
@ -80,6 +73,10 @@ void MF_trailerDecoderDialog::on_accessBitsEdit_textEdited(const QString &arg1)
} }
} }
} }
ui->C0Box->blockSignals(false);
ui->C1Box->blockSignals(false);
ui->C2Box->blockSignals(false);
ui->C3Box->blockSignals(false);
} }
void MF_trailerDecoderDialog::on_blockSizeChanged(int id, bool st) void MF_trailerDecoderDialog::on_blockSizeChanged(int id, bool st)
@ -125,3 +122,33 @@ void MF_trailerDecoderDialog::setTableItem(QTableWidget* widget, int row, int co
} }
widget->item(row, column)->setText(text); widget->item(row, column)->setText(text);
} }
void MF_trailerDecoderDialog::on_boxChanged(const QString &arg1)
{
quint8 ACBits[4];
ACBits[0] = ui->C0Box->value();
ACBits[1] = ui->C1Box->value();
ACBits[2] = ui->C2Box->value();
ACBits[3] = ui->C3Box->value();
quint8 halfBytes[6] = {0, 0, 0, 0, 0, 0};
for(int i = 0; i < 4; i++)
{
halfBytes[2] |= (((ACBits[i] >> 0) & 1) << i);
halfBytes[5] |= (((ACBits[i] >> 1) & 1) << i);
halfBytes[4] |= (((ACBits[i] >> 2) & 1) << i);
}
halfBytes[0] = (~halfBytes[5]) & 0xf;
halfBytes[1] = (~halfBytes[2]) & 0xf;
halfBytes[3] = (~halfBytes[4]) & 0xf;
QString result;
for(int i = 0; i < 3; i++)
{
result += QString::number(halfBytes[i * 2], 16);
result += QString::number(halfBytes[i * 2 + 1], 16);
result += " ";
}
result = result.toUpper();
ui->accessBitsEdit->setText(result);
}

@ -23,9 +23,11 @@ public:
private slots: private slots:
void on_accessBitsEdit_textEdited(const QString &arg1); void on_accessBitsEdit_textChanged(const QString &arg1);
void on_blockSizeChanged(int id, bool st); void on_blockSizeChanged(int id, bool st);
void on_boxChanged(const QString &arg1);
private: private:
Ui::MF_trailerDecoderDialog *ui; Ui::MF_trailerDecoderDialog *ui;
QRegularExpressionValidator* validator; QRegularExpressionValidator* validator;

@ -6,37 +6,16 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>531</width> <width>534</width>
<height>436</height> <height>507</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Trailer Decoder</string> <string>Trailer Decoder</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_7">
<item> <item>
<widget class="QLabel" name="label"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="text">
<string>Trailer Data:(Input the Access Bits, like &quot;FF 07 80 69&quot; or &quot;FF 07 80&quot;)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="accessBitsEdit"/>
</item>
<item>
<widget class="QLabel" name="isAccessBitsValidLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="QGroupBox" name="sizeGroupBox"> <widget class="QGroupBox" name="sizeGroupBox">
<property name="title"> <property name="title">
@ -63,6 +42,191 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Trailer Data:
(like &quot;FF0780&quot; or &quot;FF 07 80&quot;)</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="accessBitsEdit"/>
</item>
<item>
<widget class="QLabel" name="isAccessBitsValidLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Or set bits manually</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Cx0</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="C0Box">
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>Cx1</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="C1Box">
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>Cx2</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="C2Box">
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>Cx3</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="C3Box">
<property name="maximum">
<number>7</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</item> </item>
<item> <item>
@ -188,6 +352,16 @@ Rev. 3.2 — 23 November 2017</string>
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>Note:the Access Bits usually contains 4 bytes(8 hex symbols), but only the first 3 bytes matters. You can set the 4th byte randomly.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>

Loading…
Cancel
Save