Config fiie for official client

Unfinished
Refactor nested(), info(), chk()
pull/33/head
wh201906 3 years ago
parent 5a8ab42281
commit 03d9c601fc

@ -34,7 +34,7 @@ void Util::execCMD(const QString& cmd)
emit write(cmd + "\n"); emit write(cmd + "\n");
} }
QString Util::execCMDWithOutput(const QString& cmd, ReturnTrigger trigger) QString Util::execCMDWithOutput(const QString& cmd, ReturnTrigger trigger, bool rawOutput)
{ {
// if the trigger is empty, this function will wait trigger.waitTime then return all outputs during the wait time. // if the trigger is empty, this function will wait trigger.waitTime then return all outputs during the wait time.
// otherwise, this function will return empty string if no trigger is detected, or return outputs if any trigger is detected. // otherwise, this function will return empty string if no trigger is detected, or return outputs if any trigger is detected.
@ -78,7 +78,7 @@ QString Util::execCMDWithOutput(const QString& cmd, ReturnTrigger trigger)
} }
} }
isRequiringOutput = false; isRequiringOutput = false;
return (isResultFound || trigger.expectedOutputs.isEmpty() ? *requiredOutput : ""); return (isResultFound || trigger.expectedOutputs.isEmpty() || rawOutput ? *requiredOutput : "");
} }
void Util::delay(unsigned int msec) void Util::delay(unsigned int msec)

@ -53,7 +53,7 @@ public:
explicit Util(QObject *parent = nullptr); explicit Util(QObject *parent = nullptr);
void execCMD(const QString& cmd); void execCMD(const QString& cmd);
QString execCMDWithOutput(const QString& cmd, ReturnTrigger trigger = 10000); QString execCMDWithOutput(const QString& cmd, ReturnTrigger trigger = 10000, bool rawOutput = false);
void delay(unsigned int msec); void delay(unsigned int msec);
static ClientType getClientType(); static ClientType getClientType();
static int rawTabIndex; static int rawTabIndex;

@ -0,0 +1,62 @@
{
"mifare classic": {
"nested": {
"cmd": "hf mf nested <card type> *",
"card type": {
"mini": "0",
"1k": "1",
"2k": "2",
"4k": "4"
},
"key type": {
"A": "A",
"B": "B"
},
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
"key A index": 2,
"key B index": 4
},
"chk": {
"cmd": "hf mf chk *<card type> ?",
"card type": {
"mini": "0",
"1k": "1",
"2k": "2",
"4k": "4"
},
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
"key A index": 2,
"key B index": 3
},
"info": {
"cmd": "hf 14a info"
},
"sniff": {
"cmd": "hf mf sniff"
},
"sniff 14a": {
"cmd": "hf 14a snoop"
},
"list": {
"cmd": "hf list mf"
},
"dump": {
"cmd": "hf mf dump"
},
"restore": {
"cmd": "hf mf restore"
},
"wipe emulator": {
"cmd": "hf mf eclr"
},
"wipe Magic Card": {
"cmd": "hf mf cwipe <card type> f",
"card type": {
"mini": "0",
"1k": "1",
"2k": "2",
"4k": "4"
}
}
}
}

@ -1,18 +1,21 @@
{ {
"mifare classic": { "mifare classic": {
"nested":{ "nested": {
"cmd":"hf mf nested --<card type> --blk <block> -<key type> -k <key>", "cmd": "hf mf nested --<card type> --blk <block> -<key type> -k <key>",
"static cmd": "hf mf staticnested --<card type> --blk <block> -<key type> -k <key>",
"card type": { "card type": {
"mini": "mini", "mini": "mini",
"1k": "1k", "1k": "1k",
"2k": "2k", "2k": "2k",
"4k": "4k" "4k": "4k"
}, },
"key type":{ "key type": {
"A": "a", "A": "a",
"B": "b" "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 B index": 4
}, },
"chk": { "chk": {
"cmd": "hf mf chk --<card type>", "cmd": "hf mf chk --<card type>",
@ -22,7 +25,9 @@
"2k": "2k", "2k": "2k",
"4k": "4k" "4k": "4k"
}, },
"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 B index": 4
}, },
"info": { "info": {
"cmd": "hf 14a info" "cmd": "hf 14a info"

@ -93,20 +93,23 @@ void Mifare::setConfigMap(const QVariantMap& configMap)
qDebug() << configMap; qDebug() << configMap;
} }
// TODO: change result type QString->QMap QMap<QString, QString> Mifare::info(bool isRequiringOutput)
QString Mifare::info(bool isRequiringOutput)
{ {
QMap<QString, QString> map;
QVariantMap config = configMap["info"].toMap(); QVariantMap config = configMap["info"].toMap();
if(isRequiringOutput) if(isRequiringOutput)
{ {
QString result = util->execCMDWithOutput(config["cmd"].toString(), 500); QString result = util->execCMDWithOutput(config["cmd"].toString(), 500);
int begin, end; QStringList lineList = result.split("\n");
begin = result.indexOf("UID");
if(begin != -1) for(auto line = lineList.begin(); line != lineList.end(); line++)
{ {
end = result.indexOf("SAK", begin); if(line->contains("UID"))
end = result.indexOf("\n", end); map["UID"] = line->replace("UID", "").replace(QRegularExpression("[^0-9a-fA-F]"), "").trimmed();
return result.mid(begin, end - begin + 1); else if(line->contains("ATQA"))
map["ATQA"] = line->replace("ATQA", "").replace(QRegularExpression("[^0-9a-fA-F]"), "").trimmed();
else if(line->contains("SAK"))
map["SAK"] = line->replace("SAK", "").replace(QRegularExpression("\\[.+?\\]"), "").replace(QRegularExpression("[^0-9a-fA-F]"), "").trimmed();
} }
} }
else else
@ -114,97 +117,66 @@ QString Mifare::info(bool isRequiringOutput)
util->execCMD(config["cmd"].toString()); util->execCMD(config["cmd"].toString());
Util::gotoRawTab(); Util::gotoRawTab();
} }
return ""; return map;
} }
// TODO: Remove ClientType() detect, detect valid key by [0-9A-Fa-f]
void Mifare::chk() void Mifare::chk()
{ {
QRegularExpressionMatch reMatch; QRegularExpressionMatch reMatch;
QString result; QString result;
int offset = 0; int offset = 0;
QString data; QString data;
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) QVariantMap config = configMap["chk"].toMap();
QString cmd = config["cmd"].toString();
int keyAindex = config["key A index"].toInt();
int keyBindex = config["key B index"].toInt();
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString());
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
result = util->execCMDWithOutput(
cmd,
Util::ReturnTrigger(1000 + cardType.sector_size * 200, {"No valid", keyPattern.pattern()}));
for(int i = 0; i < cardType.sector_size; i++)
{ {
result = util->execCMDWithOutput( reMatch = keyPattern.match(result, offset);
"hf mf chk *" offset = reMatch.capturedStart();
+ QString::number(cardType.type) if(reMatch.hasMatch())
+ " ?",
Util::ReturnTrigger(1000 + cardType.sector_size * 200, {"No valid", keyPattern->pattern()}));
qDebug() << result;
for(int i = 0; i < cardType.sector_size; i++)
{ {
reMatch = keyPattern->match(result, offset); data = reMatch.captured().toUpper();
offset = reMatch.capturedStart(); offset += data.length();
if(reMatch.hasMatch()) QStringList cells = data.remove(" ").split("|");
if(!cells[keyAindex].contains(QRegularExpression("[^0-9a-fA-F]")))
{ {
data = reMatch.captured().toUpper(); keyAList->replace(i, cells[keyAindex]);
offset += data.length();
QStringList cells = data.remove(" ").split("|");
if(!cells[2].contains("?"))
{
keyAList->replace(i, cells[2]);
}
if(!cells[3].contains("?"))
{
keyBList->replace(i, cells[3]);
}
} }
} if(!cells[keyBindex].contains(QRegularExpression("[^0-9a-fA-F]")))
}
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
{
QVariantMap config = configMap["chk"].toMap();
QString cmd = config["cmd"].toString();
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString());
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
result = util->execCMDWithOutput(
cmd,
Util::ReturnTrigger(1000 + cardType.sector_size * 200, {"No valid", keyPattern.pattern()}));
qDebug() << "mf_chk_iceman_result" << result;
for(int i = 0; i < cardType.sector_size; i++)
{
reMatch = keyPattern.match(result, offset);
offset = reMatch.capturedStart();
if(reMatch.hasMatch())
{ {
data = reMatch.captured().toUpper(); keyBList->replace(i, cells[keyBindex]);
offset += data.length();
QStringList cells = data.remove(" ").split("|");
if(cells[3] == "1")
{
keyAList->replace(i, cells[2]);
}
if(cells[5] == "1")
{
keyBList->replace(i, cells[4]);
}
} }
} }
} }
data_syncWithKeyWidget(); data_syncWithKeyWidget();
} }
void Mifare::nested() void Mifare::nested(bool isStaticNested)
{ {
QVariantMap config = configMap["nested"].toMap(); QVariantMap config = configMap["nested"].toMap();
QString cmd = config["cmd"].toString(); QString cmd;
if(isStaticNested)
cmd = config["static cmd"].toString();
else
cmd = config["cmd"].toString();
int keyAindex = config["key A index"].toInt();
int keyBindex = config["key B index"].toInt();
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString()); QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString());
QRegularExpressionMatch reMatch; QRegularExpressionMatch reMatch;
QString result; QString result;
int offset = 0; int offset = 0;
QString data; QString data;
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
{ cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
result = util->execCMDWithOutput( if(cmd.contains(QRegularExpression("<.+>"))) // need at least one section key
"hf mf nested "
+ QString::number(cardType.type)
+ " *",
Util::ReturnTrigger(15000, {"Can't found", "\\|000\\|"}));
}
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
{ {
QString knownKey, knownKeyType; QString knownKey, knownKeyType;
int knownKeySector = -1; int knownKeySector = -1;
@ -227,20 +199,28 @@ void Mifare::nested()
} }
if(knownKeySector != -1) if(knownKeySector != -1)
{ {
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
cmd.replace("<block>", QString::number(cardType.blks[knownKeySector])); cmd.replace("<block>", QString::number(cardType.blks[knownKeySector]));
cmd.replace("<key type>", config["key type"].toMap()[knownKeyType].toString()); cmd.replace("<key type>", config["key type"].toMap()[knownKeyType].toString());
cmd.replace("<key>", knownKey); cmd.replace("<key>", knownKey);
result = util->execCMDWithOutput(
cmd,
Util::ReturnTrigger(15000, {"Can't authenticate", keyPattern_res->pattern()}));
} }
else else
{ {
QMessageBox::information(parent, tr("Info"), tr("Plz provide at least one known key")); QMessageBox::information(parent, tr("Info"), tr("Plz provide at least one known key"));
return;
} }
} }
result = util->execCMDWithOutput(
cmd,
Util::ReturnTrigger(15000, {"Can't found", "Can't authenticate", keyPattern_res->pattern()}),
true);
if(result.contains("static") && !isStaticNested)
{
nested(true);
return;
}
for(int i = 0; i < cardType.sector_size; i++) for(int i = 0; i < cardType.sector_size; i++)
{ {
reMatch = keyPattern.match(result, offset); reMatch = keyPattern.match(result, offset);
@ -250,13 +230,13 @@ void Mifare::nested()
data = reMatch.captured().toUpper(); data = reMatch.captured().toUpper();
offset += data.length(); offset += data.length();
QStringList cells = data.remove(" ").split("|"); QStringList cells = data.remove(" ").split("|");
if(cells[3] == "1") if(!cells[keyAindex].contains(QRegularExpression("[^0-9a-fA-F]")))
{ {
keyAList->replace(i, cells[2]); keyAList->replace(i, cells[keyAindex]);
} }
if(cells[5] == "1") if(!cells[keyBindex].contains(QRegularExpression("[^0-9a-fA-F]")))
{ {
keyBList->replace(i, cells[4]); keyBList->replace(i, cells[keyBindex]);
} }
} }
} }
@ -285,10 +265,7 @@ void Mifare::darkside()
void Mifare::sniff() void Mifare::sniff()
{ {
QVariantMap config = configMap["sniff"].toMap(); QVariantMap config = configMap["sniff"].toMap();
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) util->execCMD(config["cmd"].toString());
util->execCMD("hf mf sniff");
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
util->execCMD(config["cmd"].toString());
Util::gotoRawTab(); Util::gotoRawTab();
} }
@ -296,10 +273,7 @@ void Mifare::sniff()
void Mifare::sniff14a() void Mifare::sniff14a()
{ {
QVariantMap config = configMap["sniff 14a"].toMap(); QVariantMap config = configMap["sniff 14a"].toMap();
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) util->execCMD(config["cmd"].toString());
util->execCMD("hf 14a snoop");
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
util->execCMD(config["cmd"].toString());
Util::gotoRawTab(); Util::gotoRawTab();
} }
@ -307,10 +281,7 @@ void Mifare::sniff14a()
void Mifare::list() void Mifare::list()
{ {
QVariantMap config = configMap["sniff 14a"].toMap(); QVariantMap config = configMap["sniff 14a"].toMap();
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) util->execCMD(config["cmd"].toString());
util->execCMD("hf list mf");
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
util->execCMD(config["cmd"].toString());
Util::gotoRawTab(); Util::gotoRawTab();
} }
@ -790,37 +761,25 @@ void Mifare::restore()
void Mifare::wipeC() void Mifare::wipeC()
{ {
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) QVariantMap config = configMap["wipe Magic Card"].toMap();
{ QString cmd = config["cmd"].toString();
util->execCMD( if(cmd.contains("<card type>"))
"hf mf cwipe " cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
+ QString::number(cardType.type) util->execCMD(cmd);
+ " f");
}
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
{
QVariantMap config = configMap["wipe Magic Card"].toMap();
util->execCMD(config["cmd"].toString());
}
Util::gotoRawTab(); Util::gotoRawTab();
} }
void Mifare::setParameterC() void Mifare::setParameterC()
{ {
QString result = info(true); QMap<QString, QString> result = info(true);
if(result == "") if(result.isEmpty())
{
QMessageBox::information(parent, tr("Info"), tr("Failed to read card.")); QMessageBox::information(parent, tr("Info"), tr("Failed to read card."));
return;
}
else else
{ {
result.replace("\n", ""); MF_UID_parameterDialog dialog(result["UID"].toUpper(), result["ATQA"].toUpper(), result["SAK"].toUpper());
result.replace(QRegularExpression("\\[.\\]"), "");
result.replace("UID", "");
result.replace("ATQA", "");
result.replace("SAK", "");
result.replace(" ", "");
QStringList lis = result.split(':');
qDebug() << lis;
MF_UID_parameterDialog dialog(lis[1].toUpper(), lis[2].toUpper(), lis[3].toUpper());
connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD); connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD);
if(dialog.exec() == QDialog::Accepted) if(dialog.exec() == QDialog::Accepted)
Util::gotoRawTab(); Util::gotoRawTab();

@ -65,9 +65,9 @@ public:
static const AccessType trailerReadCondition[8][3]; static const AccessType trailerReadCondition[8][3];
static const AccessType trailerWriteCondition[8][3]; static const AccessType trailerWriteCondition[8][3];
QString info(bool isRequiringOutput = false); QMap<QString, QString> info(bool isRequiringOutput = false);
void chk(); void chk();
void nested(); void nested(bool isStaticNested = false);
void darkside(); void darkside();
void hardnested(); void hardnested();
void sniff(); void sniff();

Loading…
Cancel
Save