mirror of
https://github.com/wh201906/Proxmark3GUI.git
synced 2025-02-16 22:21:30 +08:00
Check Access Bits when writing to selected blocks
This commit is contained in:
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…
x
Reference in New Issue
Block a user