diff --git a/README.md b/README.md index e7311e3..3bde4c5 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ Great thanks to him. make make clean cp -r ../lang ./ + cp ../configs.json ./ ./Proxmark3GUI *** diff --git a/common/pm3process.cpp b/common/pm3process.cpp index c4df2af..3a7b405 100644 --- a/common/pm3process.cpp +++ b/common/pm3process.cpp @@ -109,7 +109,7 @@ void PM3Process::onTimeout() //when the proxmark3 client is unexpectedly termina { // isBusy() is a deprecated function. // It will always return false on Raspbian. -// SerialListener need to be removed. +// SerialListener needs to be removed. // // qDebug()<isBusy(); // if(!portInfo->isBusy()) diff --git a/configs.json b/configs.json new file mode 100644 index 0000000..7d67a94 --- /dev/null +++ b/configs.json @@ -0,0 +1,52 @@ +{ + "mifare classic": { + "nested":{ + "cmd":"hf mf nested -- --blk - -k ", + "card type": { + "mini": "mini", + "1k": "1k", + "2k": "2k", + "4k": "4k" + }, + "key type":{ + "A": "a", + "B": "b" + }, + "key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|" + }, + "chk": { + "cmd": "hf mf chk --", + "card type": { + "mini": "mini", + "1k": "1k", + "2k": "2k", + "4k": "4k" + }, + "key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|" + }, + "info": { + "cmd": "hf 14a info" + }, + "sniff": { + "cmd": "hf sniff" + }, + "sniff 14a": { + "cmd": "hf 14a sniff" + }, + "list": { + "cmd": "trace list -t mf" + }, + "dump": { + "cmd": "hf mf dump" + }, + "restore": { + "cmd": "hf mf restore" + }, + "wipe emulator": { + "cmd": "hf mf eclr" + }, + "wipe Magic Card": { + "cmd": "hf mf cwipe" + } + } +} \ No newline at end of file diff --git a/module/mifare.cpp b/module/mifare.cpp index 42bd333..b9346ab 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -87,31 +87,37 @@ Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent): QObject(parent) keyPattern = new QRegularExpression("\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|"); } +void Mifare::setConfigMap(const QVariantMap& configMap) +{ + this->configMap = configMap; + qDebug() << configMap; +} + +// TODO: change result type QString->QMap QString Mifare::info(bool isRequiringOutput) { - if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL || Util::getClientType() == Util::CLIENTTYPE_ICEMAN) + QVariantMap config = configMap["info"].toMap(); + if(isRequiringOutput) { - if(isRequiringOutput) - { - QString result = util->execCMDWithOutput("hf 14a info", 500); - int begin, end; - begin = result.indexOf("UID"); - if(begin != -1) - { - end = result.indexOf("SAK", begin); - end = result.indexOf("\n", end); - return result.mid(begin, end - begin + 1); - } - } - else + QString result = util->execCMDWithOutput(config["cmd"].toString(), 500); + int begin, end; + begin = result.indexOf("UID"); + if(begin != -1) { - util->execCMD("hf 14a info"); - Util::gotoRawTab(); + end = result.indexOf("SAK", begin); + end = result.indexOf("\n", end); + return result.mid(begin, end - begin + 1); } } + else + { + util->execCMD(config["cmd"].toString()); + Util::gotoRawTab(); + } return ""; } +// TODO: Remove ClientType() detect, detect valid key by [0-9A-Fa-f] void Mifare::chk() { QRegularExpressionMatch reMatch; @@ -148,14 +154,18 @@ void Mifare::chk() } 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("", config["card type"].toMap()[cardType.typeText].toString()); + result = util->execCMDWithOutput( - "hf mf chk --" - + cardType.typeText, - Util::ReturnTrigger(1000 + cardType.sector_size * 200, {"No valid", keyPattern_res->pattern()})); + 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_res->match(result, offset); + reMatch = keyPattern.match(result, offset); offset = reMatch.capturedStart(); if(reMatch.hasMatch()) { @@ -179,6 +189,9 @@ void Mifare::chk() void Mifare::nested() { + QVariantMap config = configMap["nested"].toMap(); + QString cmd = config["cmd"].toString(); + QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString()); QRegularExpressionMatch reMatch; QString result; int offset = 0; @@ -193,32 +206,33 @@ void Mifare::nested() } else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) { - QString knownKeyInfo = ""; + QString knownKey, knownKeyType; + int knownKeySector = -1; for(int i = 0; i < cardType.sector_size; i++) { if(data_isKeyValid(keyAList->at(i))) { - knownKeyInfo = " --blk " + QString::number(i * 4) + " -a -k " + keyAList->at(i); + knownKeyType = "A"; + knownKey = keyAList->at(i); + knownKeySector = i; break; } - } - if(knownKeyInfo == "") - { - for(int i = 0; i < cardType.sector_size; i++) + else if(data_isKeyValid(keyBList->at(i))) { - if(data_isKeyValid(keyBList->at(i))) - { - knownKeyInfo = " --blk " + QString::number(i * 4) + " -b -k " + keyBList->at(i); - break; - } + knownKeyType = "B"; + knownKey = keyBList->at(i); + knownKeySector = i; + break; } } - if(knownKeyInfo != "") + if(knownKeySector != -1) { + cmd.replace("", config["card type"].toMap()[cardType.typeText].toString()); + cmd.replace("", QString::number(cardType.blks[knownKeySector])); + cmd.replace("", config["key type"].toMap()[knownKeyType].toString()); + cmd.replace("", knownKey); result = util->execCMDWithOutput( - "hf mf nested --" - + cardType.typeText - + knownKeyInfo, + cmd, Util::ReturnTrigger(15000, {"Can't authenticate", keyPattern_res->pattern()})); } else @@ -229,7 +243,7 @@ void Mifare::nested() } for(int i = 0; i < cardType.sector_size; i++) { - reMatch = keyPattern_res->match(result, offset); + reMatch = keyPattern.match(result, offset); offset = reMatch.capturedStart(); if(reMatch.hasMatch()) { @@ -270,30 +284,33 @@ void Mifare::darkside() void Mifare::sniff() { + QVariantMap config = configMap["sniff"].toMap(); if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) util->execCMD("hf mf sniff"); else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) - util->execCMD("hf sniff"); + util->execCMD(config["cmd"].toString()); Util::gotoRawTab(); } void Mifare::sniff14a() { + QVariantMap config = configMap["sniff 14a"].toMap(); if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) util->execCMD("hf 14a snoop"); else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) - util->execCMD("hf 14a sniff"); + util->execCMD(config["cmd"].toString()); Util::gotoRawTab(); } void Mifare::list() { + QVariantMap config = configMap["sniff 14a"].toMap(); if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL) util->execCMD("hf list mf"); else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) - util->execCMD("trace list -t mf"); + util->execCMD(config["cmd"].toString()); Util::gotoRawTab(); } @@ -759,15 +776,15 @@ void Mifare::writeSelected(TargetType targetType) void Mifare::dump() { - if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL || Util::getClientType() == Util::CLIENTTYPE_ICEMAN) - util->execCMD("hf mf dump"); + QVariantMap config = configMap["dump"].toMap(); + util->execCMD(config["cmd"].toString()); Util::gotoRawTab(); } void Mifare::restore() { - if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL || Util::getClientType() == Util::CLIENTTYPE_ICEMAN) - util->execCMD("hf mf restore"); + QVariantMap config = configMap["restore"].toMap(); + util->execCMD(config["cmd"].toString()); Util::gotoRawTab(); } @@ -782,7 +799,8 @@ void Mifare::wipeC() } else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) { - util->execCMD("hf mf cwipe"); + QVariantMap config = configMap["wipe Magic Card"].toMap(); + util->execCMD(config["cmd"].toString()); } Util::gotoRawTab(); } @@ -833,8 +851,8 @@ void Mifare::lockC() void Mifare::wipeE() { - if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL || Util::getClientType() == Util::CLIENTTYPE_ICEMAN) - util->execCMD("hf mf eclr"); + QVariantMap config = configMap["wipe emulator"].toMap(); + util->execCMD(config["cmd"].toString()); } void Mifare::simulate() diff --git a/module/mifare.h b/module/mifare.h index 18a86e3..7fd26b7 100644 --- a/module/mifare.h +++ b/module/mifare.h @@ -11,6 +11,7 @@ #include #include #include +#include class Mifare : public QObject { Q_OBJECT @@ -113,6 +114,7 @@ public: static bool data_isACBitsValid(const QString& text, QList *returnHalfBytes = nullptr); QString data_getUID(); quint16 getTrailerBlockId(quint8 sectorId, qint8 cardTypeId = -1); // -1: use current cardtype + void setConfigMap(const QVariantMap& configMap); public slots: signals: @@ -121,6 +123,8 @@ private: Ui::MainWindow *ui; Util* util; + QVariantMap configMap; + QStringList* keyAList; QStringList* keyBList; QStringList* dataList; diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 13f5fae..9875138 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -1,6 +1,8 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include + MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) , ui(new Ui::MainWindow) @@ -38,6 +40,16 @@ MainWindow::MainWindow(QWidget *parent): mifare = new Mifare(ui, util, this); lf = new LF(ui, util, this); + QFile configList("configs.json"); + if(!configList.open(QFile::ReadOnly | QFile::Text)) + { + ; + } + + QByteArray configData = configList.readAll(); + QJsonDocument configJson(QJsonDocument::fromJson(configData)); + mifare->setConfigMap(configJson.object()["mifare classic"].toObject().toVariantMap()); + keyEventFilter = new MyEventFilter(QEvent::KeyPress); resizeEventFilter = new MyEventFilter(QEvent::Resize);