Config file for official client

Unfinished
Refactor darkside() _readblk(), loadSniff(), saveSniff()
Add extra waiting time when handling temp file of load/saveSniff()
pull/33/head
wh201906 3 years ago
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 "";
{ }
return ""; QVariantMap config = configMap["normal read block"].toMap();
} QString cmd = config["cmd"].toString();
// use the given key type to read the target block QRegularExpression dataPattern = QRegularExpression(config["data pattern"].toString());
result = util->execCMDWithOutput( cmd.replace("<block>", QString::number(blockId));
"hf mf rdbl " cmd.replace("<key type>", config["key type"].toMap()[QString((char)keyType)].toString());
+ QString::number(blockId) cmd.replace("<key>", key);
+ " " // use the given key type to read the target block
+ (char)keyType result = util->execCMDWithOutput(cmd, waitTime);
+ " "
+ key, currMatch = dataPattern.match(result);
waitTime); if(currMatch.hasMatch())
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 = currMatch.captured().toUpper(); data.replace(0, 12, key);
data.remove(" "); QList<quint8> ACBits = data_getACBits(data.mid(12, 8));
// 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(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
// 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);
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(20, 12, "????????????");
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(cmd, Util::ReturnTrigger({"loaded"})) != "")
util->execCMD(config["show cmd"].toString());
}
else
{ {
if(util->execCMDWithOutput("trace load -f " + file, Util::ReturnTrigger({"loaded"})) != "") util->execCMD(cmd);
util->execCMD("trace list -t mf");
} }
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…
Cancel
Save