Check Access Bits when writing to selected blocks

pull/14/head
wh201906 4 years ago
parent 1c273a6527
commit a3e6aa787b

@ -25,7 +25,7 @@ A GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client
## Preview
![preview](README/img/preview.png)
more previews [here](README/doc/previews.md)
[more previews](README/doc/previews.md)
***

@ -273,7 +273,7 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, Targe
{
QString data;
QString result;
bool isKeyBlock = (blockId < 128 && ((blockId + 1) % 4 == 0)) || ((blockId + 1) % 16 == 0);
bool isTrailerBlock = (blockId < 128 && ((blockId + 1) % 4 == 0)) || ((blockId + 1) % 16 == 0);
if(util->getClientType() == Util::CLIENTTYPE_OFFICIAL || util->getClientType() == Util::CLIENTTYPE_ICEMAN)
{
@ -298,7 +298,7 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, Targe
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(by Access Bits)
// if the given key type is KeyB, it will never get the KeyA from the key block
if(isKeyBlock && keyType == KEY_A) // in this case, the Access Bits is always accessible
if(isTrailerBlock && keyType == KEY_A) // in this case, the Access Bits is always accessible
{
data.replace(0, 12, key);
QList<quint8> ACBits = data_getACBits(data.mid(12, 8));
@ -307,7 +307,7 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, Targe
data.replace(20, 12, "????????????");
}
}
else if(isKeyBlock && keyType == KEY_B)
else if(isTrailerBlock && keyType == KEY_B)
{
data.replace(20, 12, key);;
data.replace(0, 12, "????????????"); // fill the keyA part with ?
@ -536,8 +536,8 @@ bool Mifare::_writeblk(int blockId, KeyType keyType, const QString& key, const Q
{
QString result;
QString input = data.toUpper();
input.remove(" ");
input.remove(" ");
if(data_isDataValid(input) != DATA_NOSPACE)
return false;
@ -601,6 +601,8 @@ void Mifare::writeSelected(TargetType targetType)
{
QList<int> failedBlocks;
QList<int> selectedBlocks;
bool yes2All = false, no2All = false;
for(int i = 0; i < cardType.block_size; i++)
{
if(ui->MF_dataWidget->item(i, 1)->checkState() == Qt::Checked)
@ -609,6 +611,29 @@ void Mifare::writeSelected(TargetType targetType)
for(int item : selectedBlocks)
{
bool result = false;
bool isTrailerBlock = (item < 128 && ((item + 1) % 4 == 0)) || ((item + 1) % 16 == 0);
if(isTrailerBlock && !data_isACBitsValid(dataList->at(item).mid(12, 8))) // trailer block is invalid
{
if(!yes2All && !no2All)
{
QMessageBox::StandardButton choice = QMessageBox::information(parent, tr("Info"),
tr("The Access Bits is invalid!\nIt could make the whole sector blocked irreversibly!\nContinue to write?"),
QMessageBox::Yes | QMessageBox::YesToAll | QMessageBox::No | QMessageBox::NoToAll);
if(choice == QMessageBox::No)
continue;
else if(choice == QMessageBox::YesToAll)
yes2All = true;
else if(QMessageBox::NoToAll)
{
no2All = true;
continue;
}
}
else if(no2All)
continue;
}
if(targetType == TARGET_MIFARE)
{
result = _writeblk(item, KEY_A, keyAList->at(data_b2s(item)), dataList->at(item), TARGET_MIFARE);
@ -1192,24 +1217,36 @@ int Mifare::data_b2s(int block)
return -1;
}
QList<quint8> Mifare::data_getACBits(const QString& text) //return empty QList if the text is invalid
bool Mifare::data_isACBitsValid(const QString& text, QList<quint8>* returnHalfBytes)
{
QString input = text;
QList<quint8> result;
input.remove(" ");
if(input.length() < 6)
{
return result;
return false;
}
input = input.left(6);
quint32 val = input.toUInt(nullptr, 16);
quint8 halfBytes[6];
QList<quint8> halfBytes;
for(int i = 0; i < 6; i++)
{
halfBytes[i] = (val >> ((5 - i) * 4)) & 0xf;
halfBytes.append((val >> ((5 - i) * 4)) & 0xf);
}
qDebug() << val;
if((~halfBytes[0] & 0xf) == halfBytes[5] && (~halfBytes[1] & 0xf) == halfBytes[2] && (~halfBytes[3] & 0xf) == halfBytes[4])
{
if(returnHalfBytes != nullptr)
*returnHalfBytes = halfBytes;
return true;
}
else
return false;
}
QList<quint8> Mifare::data_getACBits(const QString& text) //return empty QList if the text is invalid
{
QList<quint8> halfBytes, result;
if(data_isACBitsValid(text, &halfBytes))
{
for(int i = 0; i < 4; i++)
{

@ -108,6 +108,7 @@ public:
static QList<quint8> data_getACBits(const QString &text);
static int data_b2s(int block);
static bool data_isACBitsValid(const QString &text, QList<quint8> *returnHalfBytes = nullptr);
public slots:
signals:

Loading…
Cancel
Save