mirror of
https://github.com/wh201906/Proxmark3GUI.git
synced 2025-04-21 03:56:19 +08:00
Config file for official client
Unfinished Refactor darkside() _readblk(), loadSniff(), saveSniff() Add extra waiting time when handling temp file of load/saveSniff()
This commit is contained in:
parent
03d9c601fc
commit
d0bc6808d0
@ -8,15 +8,11 @@
|
|||||||
"2k": "2",
|
"2k": "2",
|
||||||
"4k": "4"
|
"4k": "4"
|
||||||
},
|
},
|
||||||
"key type": {
|
|
||||||
"A": "A",
|
|
||||||
"B": "B"
|
|
||||||
},
|
|
||||||
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
|
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
|
||||||
"key A index": 2,
|
"key A index": 2,
|
||||||
"key B index": 4
|
"key B index": 4
|
||||||
},
|
},
|
||||||
"chk": {
|
"check": {
|
||||||
"cmd": "hf mf chk *<card type> ?",
|
"cmd": "hf mf chk *<card type> ?",
|
||||||
"card type": {
|
"card type": {
|
||||||
"mini": "0",
|
"mini": "0",
|
||||||
@ -46,10 +42,10 @@
|
|||||||
"restore": {
|
"restore": {
|
||||||
"cmd": "hf mf restore"
|
"cmd": "hf mf restore"
|
||||||
},
|
},
|
||||||
"wipe emulator": {
|
"emulator wipe": {
|
||||||
"cmd": "hf mf eclr"
|
"cmd": "hf mf eclr"
|
||||||
},
|
},
|
||||||
"wipe Magic Card": {
|
"Magic Card wipe": {
|
||||||
"cmd": "hf mf cwipe <card type> f",
|
"cmd": "hf mf cwipe <card type> f",
|
||||||
"card type": {
|
"card type": {
|
||||||
"mini": "0",
|
"mini": "0",
|
||||||
@ -57,6 +53,31 @@
|
|||||||
"2k": "2",
|
"2k": "2",
|
||||||
"4k": "4"
|
"4k": "4"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"emulator read block": {
|
||||||
|
"cmd": "hf mf eget <block>",
|
||||||
|
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
|
||||||
|
},
|
||||||
|
"Magic Card read block": {
|
||||||
|
"cmd": "hf mf cgetblk <block>",
|
||||||
|
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
|
||||||
|
},
|
||||||
|
"normal read block": {
|
||||||
|
"cmd": "hf mf rdbl <block> <key type> <key>",
|
||||||
|
"key type": {
|
||||||
|
"A": "A",
|
||||||
|
"B": "B"
|
||||||
|
},
|
||||||
|
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
|
||||||
|
},
|
||||||
|
"darkside": {
|
||||||
|
"cmd": "hf mf mifare"
|
||||||
|
},
|
||||||
|
"save sniff": {
|
||||||
|
"cmd": "hf list mf -s <filename>"
|
||||||
|
},
|
||||||
|
"load sniff": {
|
||||||
|
"cmd": "hf list mf -l <filename>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@
|
|||||||
"key A index": 2,
|
"key A index": 2,
|
||||||
"key B index": 4
|
"key B index": 4
|
||||||
},
|
},
|
||||||
"chk": {
|
"check": {
|
||||||
"cmd": "hf mf chk --<card type>",
|
"cmd": "hf mf chk --<card type>",
|
||||||
"card type": {
|
"card type": {
|
||||||
"mini": "mini",
|
"mini": "mini",
|
||||||
@ -47,11 +47,37 @@
|
|||||||
"restore": {
|
"restore": {
|
||||||
"cmd": "hf mf restore"
|
"cmd": "hf mf restore"
|
||||||
},
|
},
|
||||||
"wipe emulator": {
|
"emulator wipe": {
|
||||||
"cmd": "hf mf eclr"
|
"cmd": "hf mf eclr"
|
||||||
},
|
},
|
||||||
"wipe Magic Card": {
|
"Magic Card wipe": {
|
||||||
"cmd": "hf mf cwipe"
|
"cmd": "hf mf cwipe"
|
||||||
|
},
|
||||||
|
"emulator read block": {
|
||||||
|
"cmd": "hf mf egetblk --blk <block>",
|
||||||
|
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
|
||||||
|
},
|
||||||
|
"Magic Card read block": {
|
||||||
|
"cmd": "hf mf cgetblk --blk <block>",
|
||||||
|
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
|
||||||
|
},
|
||||||
|
"normal read block": {
|
||||||
|
"cmd": "hf mf rdbl --blk <block> -<key type> -k <key>",
|
||||||
|
"key type": {
|
||||||
|
"A": "a",
|
||||||
|
"B": "b"
|
||||||
|
},
|
||||||
|
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
|
||||||
|
},
|
||||||
|
"darkside": {
|
||||||
|
"cmd": "hf mf darkside"
|
||||||
|
},
|
||||||
|
"save sniff": {
|
||||||
|
"cmd": "trace save -f <filename>"
|
||||||
|
},
|
||||||
|
"load sniff": {
|
||||||
|
"cmd": "trace load -f <filename>",
|
||||||
|
"show cmd": "trace list --buffer -t mf"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -126,7 +126,7 @@ void Mifare::chk()
|
|||||||
QString result;
|
QString result;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
QString data;
|
QString data;
|
||||||
QVariantMap config = configMap["chk"].toMap();
|
QVariantMap config = configMap["check"].toMap();
|
||||||
QString cmd = config["cmd"].toString();
|
QString cmd = config["cmd"].toString();
|
||||||
int keyAindex = config["key A index"].toInt();
|
int keyAindex = config["key A index"].toInt();
|
||||||
int keyBindex = config["key B index"].toInt();
|
int keyBindex = config["key B index"].toInt();
|
||||||
@ -254,10 +254,8 @@ void Mifare::hardnested()
|
|||||||
|
|
||||||
void Mifare::darkside()
|
void Mifare::darkside()
|
||||||
{
|
{
|
||||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
QVariantMap config = configMap["darkside"].toMap();
|
||||||
util->execCMD("hf mf mifare");
|
util->execCMD(config["cmd"].toString());
|
||||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
|
||||||
util->execCMD("hf mf darkside");
|
|
||||||
|
|
||||||
Util::gotoRawTab();
|
Util::gotoRawTab();
|
||||||
}
|
}
|
||||||
@ -280,7 +278,7 @@ void Mifare::sniff14a()
|
|||||||
|
|
||||||
void Mifare::list()
|
void Mifare::list()
|
||||||
{
|
{
|
||||||
QVariantMap config = configMap["sniff 14a"].toMap();
|
QVariantMap config = configMap["list"].toMap();
|
||||||
util->execCMD(config["cmd"].toString());
|
util->execCMD(config["cmd"].toString());
|
||||||
|
|
||||||
Util::gotoRawTab();
|
Util::gotoRawTab();
|
||||||
@ -293,88 +291,73 @@ QString Mifare::_readblk(int blockId, KeyType keyType, const QString& key, Targe
|
|||||||
QRegularExpressionMatch currMatch;
|
QRegularExpressionMatch currMatch;
|
||||||
bool isTrailerBlock = (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)
|
if(targetType == TARGET_MIFARE)
|
||||||
{
|
{
|
||||||
if(targetType == TARGET_MIFARE)
|
if(!data_isKeyValid(key))
|
||||||
{
|
{
|
||||||
if(!data_isKeyValid(key))
|
return "";
|
||||||
|
}
|
||||||
|
QVariantMap config = configMap["normal read block"].toMap();
|
||||||
|
QString cmd = config["cmd"].toString();
|
||||||
|
QRegularExpression dataPattern = QRegularExpression(config["data pattern"].toString());
|
||||||
|
cmd.replace("<block>", QString::number(blockId));
|
||||||
|
cmd.replace("<key type>", config["key type"].toMap()[QString((char)keyType)].toString());
|
||||||
|
cmd.replace("<key>", key);
|
||||||
|
// use the given key type to read the target block
|
||||||
|
result = util->execCMDWithOutput(cmd, waitTime);
|
||||||
|
|
||||||
|
currMatch = dataPattern.match(result);
|
||||||
|
if(currMatch.hasMatch())
|
||||||
|
{
|
||||||
|
data = currMatch.captured().toUpper();
|
||||||
|
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(isTrailerBlock && keyType == KEY_A) // in this case, the Access Bits is always accessible
|
||||||
{
|
{
|
||||||
return "";
|
data.replace(0, 12, key);
|
||||||
}
|
QList<quint8> ACBits = data_getACBits(data.mid(12, 8));
|
||||||
// use the given key type to read the target block
|
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
|
||||||
result = util->execCMDWithOutput(
|
|
||||||
"hf mf rdbl "
|
|
||||||
+ QString::number(blockId)
|
|
||||||
+ " "
|
|
||||||
+ (char)keyType
|
|
||||||
+ " "
|
|
||||||
+ key,
|
|
||||||
waitTime);
|
|
||||||
currMatch = dataPattern->match(result);
|
|
||||||
if(currMatch.hasMatch())
|
|
||||||
{
|
|
||||||
data = currMatch.captured().toUpper();
|
|
||||||
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(isTrailerBlock && keyType == KEY_A) // in this case, the Access Bits is always accessible
|
|
||||||
{
|
{
|
||||||
data.replace(0, 12, key);
|
data.replace(20, 12, "????????????");
|
||||||
QList<quint8> ACBits = data_getACBits(data.mid(12, 8));
|
|
||||||
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
|
|
||||||
{
|
|
||||||
data.replace(20, 12, "????????????");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(isTrailerBlock && keyType == KEY_B)
|
|
||||||
{
|
|
||||||
data.replace(20, 12, key);;
|
|
||||||
data.replace(0, 12, "????????????"); // fill the keyA part with ?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(isTrailerBlock && keyType == KEY_B)
|
||||||
data = "";
|
|
||||||
}
|
|
||||||
else if(targetType == TARGET_UID)
|
|
||||||
{
|
|
||||||
result = util->execCMDWithOutput(
|
|
||||||
"hf mf cgetblk "
|
|
||||||
+ QString::number(blockId),
|
|
||||||
waitTime);
|
|
||||||
currMatch = dataPattern->match(result);
|
|
||||||
if(currMatch.hasMatch())
|
|
||||||
{
|
{
|
||||||
data = currMatch.captured().toUpper();
|
data.replace(20, 12, key);;
|
||||||
data.remove(" ");
|
data.replace(0, 12, "????????????"); // fill the keyA part with ?
|
||||||
}
|
}
|
||||||
else
|
|
||||||
data = "";
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
data = "";
|
||||||
}
|
}
|
||||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
else if(targetType == TARGET_UID)
|
||||||
{
|
{
|
||||||
if(targetType == TARGET_EMULATOR)
|
QVariantMap config = configMap["Magic Card read block"].toMap();
|
||||||
|
QString cmd = config["cmd"].toString();
|
||||||
|
QRegularExpression dataPattern = QRegularExpression(config["data pattern"].toString());
|
||||||
|
cmd.replace("<block>", QString::number(blockId));
|
||||||
|
result = util->execCMDWithOutput(cmd, waitTime);
|
||||||
|
currMatch = dataPattern.match(result);
|
||||||
|
if(currMatch.hasMatch())
|
||||||
{
|
{
|
||||||
result = util->execCMDWithOutput(
|
data = currMatch.captured().toUpper();
|
||||||
"hf mf eget "
|
|
||||||
+ QString::number(blockId),
|
|
||||||
150);
|
|
||||||
data = dataPattern->match(result).captured().toUpper();
|
|
||||||
data.remove(" ");
|
data.remove(" ");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
data = "";
|
||||||
}
|
}
|
||||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
else if(targetType == TARGET_EMULATOR)
|
||||||
{
|
{
|
||||||
if(targetType == TARGET_EMULATOR)
|
QVariantMap config = configMap["emulator read block"].toMap();
|
||||||
{
|
QString cmd = config["cmd"].toString();
|
||||||
result = util->execCMDWithOutput(
|
QRegularExpression dataPattern = QRegularExpression(config["data pattern"].toString());
|
||||||
"hf mf egetblk "
|
cmd.replace("<block>", QString::number(blockId));
|
||||||
+ QString::number(blockId),
|
result = util->execCMDWithOutput(cmd, 150);
|
||||||
150);
|
data = dataPattern.match(result).captured().toUpper();
|
||||||
data = dataPattern->match(result).captured().toUpper();
|
data.remove(" ");
|
||||||
data.remove(" ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +744,7 @@ void Mifare::restore()
|
|||||||
|
|
||||||
void Mifare::wipeC()
|
void Mifare::wipeC()
|
||||||
{
|
{
|
||||||
QVariantMap config = configMap["wipe Magic Card"].toMap();
|
QVariantMap config = configMap["Magic Card wipe"].toMap();
|
||||||
QString cmd = config["cmd"].toString();
|
QString cmd = config["cmd"].toString();
|
||||||
if(cmd.contains("<card type>"))
|
if(cmd.contains("<card type>"))
|
||||||
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
|
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
|
||||||
@ -810,7 +793,7 @@ void Mifare::lockC()
|
|||||||
|
|
||||||
void Mifare::wipeE()
|
void Mifare::wipeE()
|
||||||
{
|
{
|
||||||
QVariantMap config = configMap["wipe emulator"].toMap();
|
QVariantMap config = configMap["emulator wipe"].toMap();
|
||||||
util->execCMD(config["cmd"].toString());
|
util->execCMD(config["cmd"].toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,12 +807,17 @@ void Mifare::simulate()
|
|||||||
|
|
||||||
void Mifare::loadSniff(const QString& file)
|
void Mifare::loadSniff(const QString& file)
|
||||||
{
|
{
|
||||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
QVariantMap config = configMap["load sniff"].toMap();
|
||||||
util->execCMD("hf list mf -l " + file);
|
QString cmd = config["cmd"].toString();
|
||||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
cmd.replace("<filename>", file);
|
||||||
|
if(config.contains("show cmd"))
|
||||||
{
|
{
|
||||||
if(util->execCMDWithOutput("trace load -f " + file, Util::ReturnTrigger({"loaded"})) != "")
|
if(util->execCMDWithOutput(cmd, Util::ReturnTrigger({"loaded"})) != "")
|
||||||
util->execCMD("trace list -t mf");
|
util->execCMD(config["show cmd"].toString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
util->execCMD(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
Util::gotoRawTab();
|
Util::gotoRawTab();
|
||||||
@ -837,10 +825,10 @@ void Mifare::loadSniff(const QString& file)
|
|||||||
|
|
||||||
void Mifare::saveSniff(const QString& file)
|
void Mifare::saveSniff(const QString& file)
|
||||||
{
|
{
|
||||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
QVariantMap config = configMap["save sniff"].toMap();
|
||||||
util->execCMD("hf list mf -s " + file);
|
QString cmd = config["cmd"].toString();
|
||||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
cmd.replace("<filename>", file);
|
||||||
util->execCMD("trace save -f " + file);
|
util->execCMD(cmd);
|
||||||
|
|
||||||
Util::gotoRawTab();
|
Util::gotoRawTab();
|
||||||
}
|
}
|
||||||
|
@ -866,15 +866,16 @@ void MainWindow::on_MF_Sniff_loadButton_clicked() // use a tmp file to support c
|
|||||||
QString filename = "";
|
QString filename = "";
|
||||||
|
|
||||||
title = tr("Plz select the trace file:");
|
title = tr("Plz select the trace file:");
|
||||||
filename = QFileDialog::getOpenFileName(this, title, "./", tr("Trace Files(*.trc);;All Files(*.*)"));
|
filename = QFileDialog::getOpenFileName(this, title, clientWorkingDir->absolutePath(), tr("Trace Files(*.trc);;All Files(*.*)"));
|
||||||
qDebug() << filename;
|
qDebug() << filename;
|
||||||
if(filename != "")
|
if(filename != "")
|
||||||
{
|
{
|
||||||
QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc";
|
QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc";
|
||||||
if(QFile::copy(filename, "./" + tmpFile))
|
if(QFile::copy(filename, clientWorkingDir->absolutePath() + "/" + tmpFile))
|
||||||
{
|
{
|
||||||
mifare->loadSniff(tmpFile);
|
mifare->loadSniff(tmpFile);
|
||||||
QFile::remove("./" + tmpFile);
|
util->delay(3000);
|
||||||
|
QFile::remove(clientWorkingDir->absolutePath() + "/" + tmpFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -889,17 +890,23 @@ void MainWindow::on_MF_Sniff_saveButton_clicked()
|
|||||||
QString filename = "";
|
QString filename = "";
|
||||||
|
|
||||||
title = tr("Plz select the location to save trace file:");
|
title = tr("Plz select the location to save trace file:");
|
||||||
filename = QFileDialog::getSaveFileName(this, title, "./", tr("Trace Files(*.trc)"));
|
filename = QFileDialog::getSaveFileName(this, title, clientWorkingDir->absolutePath(), tr("Trace Files(*.trc)"));
|
||||||
qDebug() << filename;
|
qDebug() << filename;
|
||||||
if(filename != "")
|
if(filename != "")
|
||||||
{
|
{
|
||||||
QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc";
|
QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc";
|
||||||
mifare->saveSniff(tmpFile);
|
mifare->saveSniff(tmpFile);
|
||||||
if(!QFile::copy("./" + tmpFile, filename))
|
for(int i = 0; i < 100; i++)
|
||||||
|
{
|
||||||
|
util->delay(100);
|
||||||
|
if(QFile::exists(clientWorkingDir->absolutePath() + "/" + tmpFile))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!QFile::copy(clientWorkingDir->absolutePath() + "/" + tmpFile, filename))
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename);
|
QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename);
|
||||||
}
|
}
|
||||||
QFile::remove("./" + tmpFile);
|
QFile::remove(clientWorkingDir->absolutePath() + "/" + tmpFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="mifareTab">
|
<widget class="QWidget" name="mifareTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user