mirror of
https://github.com/wh201906/Proxmark3GUI.git
synced 2025-02-17 06:31:33 +08:00
commit
5f1df6782a
@ -17,22 +17,36 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
common/pm3process.cpp \
|
||||||
pm3process.cpp
|
common/util.cpp \
|
||||||
|
module/mifare.cpp \
|
||||||
|
ui/mf_uid_parameterdialog.cpp \
|
||||||
|
ui/mainwindow.cpp \
|
||||||
|
ui/mf_attack_hardnesteddialog.cpp \
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
mainwindow.h \
|
common/pm3process.h \
|
||||||
pm3process.h
|
common/util.h \
|
||||||
|
module/mifare.h \
|
||||||
|
ui/mf_uid_parameterdialog.h \
|
||||||
|
ui/mainwindow.h \
|
||||||
|
ui/mf_attack_hardnesteddialog.h \
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
mainwindow.ui
|
ui/mf_uid_parameterdialog.ui \
|
||||||
|
ui/mainwindow.ui \
|
||||||
|
ui/mf_attack_hardnesteddialog.ui
|
||||||
|
|
||||||
|
TRANSLATIONS += \
|
||||||
|
lang/zh_CN.ts \
|
||||||
|
lang/en_US.ts
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
!isEmpty(target.path): INSTALLS += target
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
VERSION = 0.0.1
|
VERSION = 0.1
|
||||||
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
||||||
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
||||||
QMAKE_TARGET_COMPANY = "wh201906"
|
QMAKE_TARGET_COMPANY = "wh201906"
|
||||||
|
32
README.md
32
README.md
@ -1,9 +1,35 @@
|
|||||||
# Proxmark3GUI
|
# Proxmark3GUI
|
||||||
A GUI for Proxmark3 client
|
A GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client
|
||||||
|
|
||||||
|
[中文](README/README.zh_CN.md)
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
Update Log:
|
## Features
|
||||||
|
|
||||||
## V0.0.1
|
+ Support raw commands of Proxmark3 client
|
||||||
|
+ Have a friendly UI to test Mifare cards
|
||||||
|
+ Easy to edit Mifare data files
|
||||||
|
+ Support binary(.bin .dump) files and text(.eml) files
|
||||||
|
+ ...
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Previews
|
||||||
|
![nested_attack](README/mf_nested_attack.gif)
|
||||||
|
|
||||||
|
![mf_load_file](README/mf_load_file.gif)
|
||||||
|
|
||||||
|
![mf_edit_file](README/mf_edit_file.gif)
|
||||||
|
|
||||||
|
![raw_command](README/raw_command.gif)
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Update Log:
|
||||||
|
|
||||||
|
### V0.1
|
||||||
|
+ Able to deal with Mifare card and related files
|
||||||
|
|
||||||
|
### V0.0.1
|
||||||
+ a dumb version with a useless GUI and a serial choose box.
|
+ a dumb version with a useless GUI and a serial choose box.
|
35
README/README.zh_CN.md
Normal file
35
README/README.zh_CN.md
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Proxmark3GUI
|
||||||
|
一个自制的[Proxmark3](https://github.com/Proxmark/proxmark3) GUI
|
||||||
|
|
||||||
|
[English](../README.md)
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 特色功能
|
||||||
|
|
||||||
|
+ 支持直接输入PM3命令
|
||||||
|
+ 有针对于Mifare卡(IC卡)的图形界面
|
||||||
|
+ 支持编辑Mifare扇区数据文件
|
||||||
|
+ 可以打开二进制/文本格式的扇区数据文件
|
||||||
|
+ ...
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 预览图
|
||||||
|
![nested_attack](mf_nested_attack.gif)
|
||||||
|
|
||||||
|
![mf_load_file](mf_load_file.gif)
|
||||||
|
|
||||||
|
![mf_edit_file](mf_edit_file.gif)
|
||||||
|
|
||||||
|
![raw_command](raw_command.gif)
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 更新日志:
|
||||||
|
|
||||||
|
### V0.1
|
||||||
|
+ 支持处理Mifare卡片及相关数据文件
|
||||||
|
|
||||||
|
### V0.0.1
|
||||||
|
+ 一个带串口选择框的实验版本
|
BIN
README/mf_edit_file.gif
Normal file
BIN
README/mf_edit_file.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 MiB |
BIN
README/mf_load_file.gif
Normal file
BIN
README/mf_load_file.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 650 KiB |
BIN
README/mf_nested_attack.gif
Normal file
BIN
README/mf_nested_attack.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 637 KiB |
BIN
README/raw_command.gif
Normal file
BIN
README/raw_command.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 857 KiB |
102
common/pm3process.cpp
Normal file
102
common/pm3process.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include "pm3process.h"
|
||||||
|
|
||||||
|
PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent)
|
||||||
|
{
|
||||||
|
moveToThread(thread);
|
||||||
|
setProcessChannelMode(PM3Process::MergedChannels);
|
||||||
|
isRequiringOutput = false;
|
||||||
|
requiredOutput = new QString();
|
||||||
|
serialListener = new QTimer(); // if using new QTimer(this), the debug output will show "Cannot create children for a parent that is in a different thread."
|
||||||
|
serialListener->moveToThread(this->thread());// I've tried many ways to creat a QTimer instance, but all of the instances are in the main thread(UI thread), so I have to move it manually
|
||||||
|
serialListener->setInterval(1000);
|
||||||
|
serialListener->setTimerType(Qt::VeryCoarseTimer);
|
||||||
|
connect(serialListener, &QTimer::timeout, this, &PM3Process::onTimeout);
|
||||||
|
connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::connectPM3(const QString path, const QString port)
|
||||||
|
{
|
||||||
|
setRequiringOutput(true);
|
||||||
|
|
||||||
|
// using "-f" option to make the client output flushed after every print.
|
||||||
|
start(path, QStringList() << port << "-f", QProcess::Unbuffered | QProcess::ReadWrite);
|
||||||
|
if(waitForStarted(10000))
|
||||||
|
{
|
||||||
|
while(waitForReadyRead(1000))
|
||||||
|
;
|
||||||
|
setRequiringOutput(false);
|
||||||
|
QString result = *requiredOutput;
|
||||||
|
if(result.indexOf("os: ") != -1) // make sure the PM3 is connected
|
||||||
|
{
|
||||||
|
result = result.mid(result.indexOf("os: "));
|
||||||
|
result = result.left(result.indexOf("\r\n"));
|
||||||
|
result = result.mid(3, result.lastIndexOf(" ") - 3);
|
||||||
|
emit PM3StatedChanged(true, result);
|
||||||
|
setSerialListener(port, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::setRequiringOutput(bool st)
|
||||||
|
{
|
||||||
|
isRequiringOutput = st;
|
||||||
|
if(isRequiringOutput)
|
||||||
|
requiredOutput->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PM3Process::waitForReadyRead(int msecs)
|
||||||
|
{
|
||||||
|
return QProcess::waitForReadyRead(msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::setSerialListener(const QString& name, bool state)
|
||||||
|
{
|
||||||
|
if(state)
|
||||||
|
{
|
||||||
|
portInfo = new QSerialPortInfo(name);
|
||||||
|
serialListener->start();
|
||||||
|
qDebug() << serialListener->thread();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serialListener->stop();
|
||||||
|
delete portInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::onTimeout() //when the proxmark3 client is unexpectedly terminated or the PM3 hardware is removed, the isBusy() will return false(only tested on Windows);
|
||||||
|
{
|
||||||
|
// qDebug()<<portInfo->isBusy();
|
||||||
|
if(!portInfo->isBusy())
|
||||||
|
{
|
||||||
|
kill();
|
||||||
|
emit PM3StatedChanged(false);
|
||||||
|
setSerialListener("", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::testThread()
|
||||||
|
{
|
||||||
|
qDebug() << "PM3:" << QThread::currentThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qint64 PM3Process::write(QString data)
|
||||||
|
{
|
||||||
|
return QProcess::write(data.toLatin1());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::onReadyRead()
|
||||||
|
{
|
||||||
|
QString out = readAll();
|
||||||
|
if(isRequiringOutput)
|
||||||
|
requiredOutput->append(out);
|
||||||
|
if(out != "")
|
||||||
|
{
|
||||||
|
// qDebug() << "PM3Process::onReadyRead:" << out;
|
||||||
|
emit newOutput(out);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
39
common/pm3process.h
Normal file
39
common/pm3process.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef PM3PROCESS_H
|
||||||
|
#define PM3PROCESS_H
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QtSerialPort/QSerialPortInfo>
|
||||||
|
#include <QtSerialPort/QSerialPort>
|
||||||
|
|
||||||
|
class PM3Process : public QProcess
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit PM3Process(QThread* thread, QObject* parent = nullptr);
|
||||||
|
bool waitForReadyRead(int msecs = 2000);
|
||||||
|
|
||||||
|
void testThread();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void connectPM3(const QString path, const QString port);
|
||||||
|
void setSerialListener(const QString &name, bool state);
|
||||||
|
qint64 write(QString data);
|
||||||
|
private slots:
|
||||||
|
void onTimeout();
|
||||||
|
void onReadyRead();
|
||||||
|
private:
|
||||||
|
bool isRequiringOutput;
|
||||||
|
QString* requiredOutput; // It only works in this class now
|
||||||
|
void setRequiringOutput(bool st);// It only works in this class now
|
||||||
|
QTimer* serialListener;
|
||||||
|
QSerialPortInfo* portInfo;
|
||||||
|
signals:
|
||||||
|
void PM3StatedChanged(bool st, QString info = "");
|
||||||
|
void newOutput(QString output);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PM3PROCESS_H
|
52
common/util.cpp
Normal file
52
common/util.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
Util::Util(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
isRequiringOutput = false;
|
||||||
|
requiredOutput = new QString();
|
||||||
|
timeStamp = QTime::currentTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::processOutput(QString output)
|
||||||
|
{
|
||||||
|
// qDebug() << "Util::processOutput:" << output;
|
||||||
|
if(isRequiringOutput)
|
||||||
|
{
|
||||||
|
requiredOutput->append(output);
|
||||||
|
timeStamp = QTime::currentTime();
|
||||||
|
}
|
||||||
|
emit refreshOutput(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::execCMD(QString cmd)
|
||||||
|
{
|
||||||
|
qDebug() << cmd;
|
||||||
|
emit write(cmd + "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Util::execCMDWithOutput(QString cmd, unsigned long timeout)
|
||||||
|
{
|
||||||
|
QTime currTime = QTime::currentTime();
|
||||||
|
QTime targetTime = QTime::currentTime().addMSecs(timeout);
|
||||||
|
isRequiringOutput = true;
|
||||||
|
requiredOutput->clear();
|
||||||
|
execCMD(cmd);
|
||||||
|
while( QTime::currentTime() < targetTime)
|
||||||
|
{
|
||||||
|
QApplication::processEvents();
|
||||||
|
if(timeStamp > currTime)
|
||||||
|
{
|
||||||
|
currTime = timeStamp;
|
||||||
|
targetTime = timeStamp.addMSecs(timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isRequiringOutput = false;
|
||||||
|
return *requiredOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::delay(unsigned int msec)
|
||||||
|
{
|
||||||
|
QTime timer = QTime::currentTime().addMSecs(msec);
|
||||||
|
while( QTime::currentTime() < timer )
|
||||||
|
QApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||||
|
}
|
33
common/util.h
Normal file
33
common/util.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef UTIL_H
|
||||||
|
#define UTIL_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QTime>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
class Util : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Util(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void execCMD(QString cmd);
|
||||||
|
QString execCMDWithOutput(QString cmd, unsigned long timeout = 2000);
|
||||||
|
void delay(unsigned int msec);
|
||||||
|
public slots:
|
||||||
|
void processOutput(QString output);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isRequiringOutput;
|
||||||
|
QString* requiredOutput;
|
||||||
|
QTime timeStamp;
|
||||||
|
signals:
|
||||||
|
void refreshOutput(const QString& output);
|
||||||
|
void write(QString data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UTIL_H
|
608
lang/en_US.ts
Normal file
608
lang/en_US.ts
Normal file
@ -0,0 +1,608 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="en_US">
|
||||||
|
<context>
|
||||||
|
<name>MF_Attack_hardnestedDialog</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="14"/>
|
||||||
|
<source>Hardnested Attack</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="20"/>
|
||||||
|
<source>Known Block:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="29"/>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="104"/>
|
||||||
|
<source>Block:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="68"/>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="143"/>
|
||||||
|
<source>A</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="73"/>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="148"/>
|
||||||
|
<source>B</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="95"/>
|
||||||
|
<source>Target Block:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MF_UID_parameterDialog</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="14"/>
|
||||||
|
<source>Set Parameter</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="22"/>
|
||||||
|
<source>UID:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="32"/>
|
||||||
|
<source>ATQA:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="42"/>
|
||||||
|
<source>SAK:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="23"/>
|
||||||
|
<source>Proxmark3GUI</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="56"/>
|
||||||
|
<source>Path:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="80"/>
|
||||||
|
<source>Refresh</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="87"/>
|
||||||
|
<source>Connect</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="94"/>
|
||||||
|
<source>Disconnect</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="113"/>
|
||||||
|
<source>Mifare</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="206"/>
|
||||||
|
<source>>></source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="231"/>
|
||||||
|
<source><<</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="263"/>
|
||||||
|
<source>F</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="320"/>
|
||||||
|
<source>Card Type</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="335"/>
|
||||||
|
<source>MINI</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="342"/>
|
||||||
|
<source>1K</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="352"/>
|
||||||
|
<source>2K</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="359"/>
|
||||||
|
<source>4K</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="369"/>
|
||||||
|
<source>File</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="387"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="944"/>
|
||||||
|
<source>Load</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="400"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="957"/>
|
||||||
|
<source>Save</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="420"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="534"/>
|
||||||
|
<source>Data</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="430"/>
|
||||||
|
<source>Key</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="440"/>
|
||||||
|
<source>Attack</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="465"/>
|
||||||
|
<source>Card Info</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="478"/>
|
||||||
|
<source>Check Default</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="491"/>
|
||||||
|
<source>Nested</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="498"/>
|
||||||
|
<source>Hardnested</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="523"/>
|
||||||
|
<source>Read/Write</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="533"/>
|
||||||
|
<source>Block:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="565"/>
|
||||||
|
<source>Key:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="584"/>
|
||||||
|
<source>Key Type:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="604"/>
|
||||||
|
<source>A</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="609"/>
|
||||||
|
<source>B</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="632"/>
|
||||||
|
<source>Normal(Require Password)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="647"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="736"/>
|
||||||
|
<source>Read Block</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="654"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="743"/>
|
||||||
|
<source>Write Block</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="661"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="750"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="850"/>
|
||||||
|
<source>Read All</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="668"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="757"/>
|
||||||
|
<source>Write All</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="687"/>
|
||||||
|
<source>Dump</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="700"/>
|
||||||
|
<source>Restore</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="710"/>
|
||||||
|
<source>Chinese Magic Card(Without Password)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="722"/>
|
||||||
|
<source>Lock UFUID Card</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="729"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="461"/>
|
||||||
|
<source>About UID Card</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="770"/>
|
||||||
|
<source>Set Parameter</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="789"/>
|
||||||
|
<source>Wipe</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="815"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="870"/>
|
||||||
|
<source>Simulate</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="843"/>
|
||||||
|
<source>Load from data above</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="413"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="863"/>
|
||||||
|
<source>Clear</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="893"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="924"/>
|
||||||
|
<source>Sniff</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="931"/>
|
||||||
|
<source>List Sniff Data</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="983"/>
|
||||||
|
<source>RawCommand</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1030"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="143"/>
|
||||||
|
<source>History:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1062"/>
|
||||||
|
<source>ClearHistory</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1081"/>
|
||||||
|
<source>Send</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1088"/>
|
||||||
|
<source>ClearOutput</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="77"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="179"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="229"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="246"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="259"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="278"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="291"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="314"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="327"/>
|
||||||
|
<source>Info</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="77"/>
|
||||||
|
<source>Plz choose a port first</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="91"/>
|
||||||
|
<source>Connected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="95"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="105"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="524"/>
|
||||||
|
<source>Not Connected</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="272"/>
|
||||||
|
<source>Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml);;All Files(*.*)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="278"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="291"/>
|
||||||
|
<source>Failed to open</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="179"/>
|
||||||
|
<source>When Changeing card type, the data and keys in this app will be cleard.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="179"/>
|
||||||
|
<source>Continue?</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="208"/>
|
||||||
|
<source>Plz select the font of data widget and key widget</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="229"/>
|
||||||
|
<source>Data must consists of 32 Hex symbols(Whitespace is allowed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="246"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="259"/>
|
||||||
|
<source>Key must consists of 12 Hex symbols(Whitespace is allowed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="271"/>
|
||||||
|
<source>Plz select the data file:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="284"/>
|
||||||
|
<source>Plz select the key file:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="285"/>
|
||||||
|
<source>Binary Key Files(*.bin *.dump);;Binary Data Files(*.bin *.dump);;All Files(*.*)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="307"/>
|
||||||
|
<source>Plz select the location to save data file:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="308"/>
|
||||||
|
<source>Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="314"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="327"/>
|
||||||
|
<source>Failed to save to</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="320"/>
|
||||||
|
<source>Plz select the location to save key file:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="321"/>
|
||||||
|
<source>Binary Key Files(*.bin *.dump)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="446"/>
|
||||||
|
<source> Normally, the Block 0 of a typical Mifare card, which contains the UID, is locked during the manufacture. Users cannot write anything to Block 0 or set a new UID to a normal Mifare card.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="447"/>
|
||||||
|
<source> Chinese Magic Cards(aka UID Cards) are some special cards whose Block 0 are writeable. And you can change UID by writing to it.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="449"/>
|
||||||
|
<source>There are two versions of Chinese Magic Cards, the Gen1 and the Gen2.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="450"/>
|
||||||
|
<source> Gen1:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="450"/>
|
||||||
|
<source> also called UID card in China. It responses to some backdoor commands so you can access any blocks without password. The Proxmark3 has a bunch of related commands(csetblk, cgetblk, ...) to deal with this type of card, and my GUI also support these commands.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="451"/>
|
||||||
|
<source> Gen2:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="451"/>
|
||||||
|
<source> doesn't response to the backdoor commands, which means that a reader cannot detect whether it is a Chinese Magic Card or not by sending backdoor commands.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="453"/>
|
||||||
|
<source>There are some types of Chinese Magic Card Gen2.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="454"/>
|
||||||
|
<source> CUID Card:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="454"/>
|
||||||
|
<source> the Block 0 is writeable, you can write to this block repeatedly by normal wrbl command.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="455"/>
|
||||||
|
<source> (hf mf wrbl 0 A FFFFFFFFFFFF <the data you want to write>)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="456"/>
|
||||||
|
<source> FUID Card:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="456"/>
|
||||||
|
<source> you can only write to Block 0 once. After that, it seems like a typical Mifare card(Block 0 cannot be written to).</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="457"/>
|
||||||
|
<source> (some readers might try changing the Block 0, which could detect the CUID Card. In that case, you should use FUID card.)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="458"/>
|
||||||
|
<source> UFUID Card:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="458"/>
|
||||||
|
<source> It behaves like a CUID card(or UID card? I'm not sure) before you send some special command to lock it. Once it is locked, you cannot change its Block 0(just like a typical Mifare card).</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="460"/>
|
||||||
|
<source> Seemingly, these Chinese Magic Cards are more easily to be compromised by Nested Attack(it takes little time to get an unknown key).</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="525"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="642"/>
|
||||||
|
<source>Idle</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="532"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="541"/>
|
||||||
|
<source>Sec</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="533"/>
|
||||||
|
<source>Blk</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="542"/>
|
||||||
|
<source>KeyA</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="543"/>
|
||||||
|
<source>KeyB</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="579"/>
|
||||||
|
<source>HW Version:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="581"/>
|
||||||
|
<source>PM3:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="583"/>
|
||||||
|
<source>State:</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="638"/>
|
||||||
|
<source>Running</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Mifare</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="289"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="386"/>
|
||||||
|
<source>Success!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="289"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="293"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="386"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="390"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="425"/>
|
||||||
|
<source>Info</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="293"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="390"/>
|
||||||
|
<source>Failed!</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="425"/>
|
||||||
|
<source>Failed to read card.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
649
lang/zh_CN.ts
Normal file
649
lang/zh_CN.ts
Normal file
@ -0,0 +1,649 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE TS>
|
||||||
|
<TS version="2.1" language="zh_CN">
|
||||||
|
<context>
|
||||||
|
<name>MF_Attack_hardnestedDialog</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="14"/>
|
||||||
|
<source>Hardnested Attack</source>
|
||||||
|
<translation>Hardnested攻击</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Known Key:</source>
|
||||||
|
<translation type="obsolete">已知Key:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="20"/>
|
||||||
|
<source>Known Block:</source>
|
||||||
|
<translation>已知块:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="29"/>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="104"/>
|
||||||
|
<source>Block:</source>
|
||||||
|
<translation>块:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="68"/>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="143"/>
|
||||||
|
<source>A</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="73"/>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="148"/>
|
||||||
|
<source>B</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_attack_hardnesteddialog.ui" line="95"/>
|
||||||
|
<source>Target Block:</source>
|
||||||
|
<translation>目标块:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Target Block: </source>
|
||||||
|
<translation type="vanished">目标块:</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MF_UID_parameterDialog</name>
|
||||||
|
<message>
|
||||||
|
<source>Dialog</source>
|
||||||
|
<translation type="vanished">对话框</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="14"/>
|
||||||
|
<source>Set Parameter</source>
|
||||||
|
<translation>设置卡参数</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="22"/>
|
||||||
|
<source>UID:</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="32"/>
|
||||||
|
<source>ATQA:</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mf_uid_parameterdialog.ui" line="42"/>
|
||||||
|
<source>SAK:</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>The parameter will not change if you leave it empty.</source>
|
||||||
|
<translation type="vanished">如果留空,则对应参数将保持不变</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>MainWindow</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="23"/>
|
||||||
|
<source>Proxmark3GUI</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="56"/>
|
||||||
|
<source>Path:</source>
|
||||||
|
<translation>路径:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="80"/>
|
||||||
|
<source>Refresh</source>
|
||||||
|
<translation>刷新端口</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="87"/>
|
||||||
|
<source>Connect</source>
|
||||||
|
<translation>连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="94"/>
|
||||||
|
<source>Disconnect</source>
|
||||||
|
<translation>断开</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="113"/>
|
||||||
|
<source>Mifare</source>
|
||||||
|
<translation>Mifare(IC)卡</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="206"/>
|
||||||
|
<source>>></source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="231"/>
|
||||||
|
<source><<</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="263"/>
|
||||||
|
<source>F</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="320"/>
|
||||||
|
<source>Card Type</source>
|
||||||
|
<translation>卡类型</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="335"/>
|
||||||
|
<source>MINI</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="342"/>
|
||||||
|
<source>1K</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="352"/>
|
||||||
|
<source>2K</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="359"/>
|
||||||
|
<source>4K</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="369"/>
|
||||||
|
<source>File</source>
|
||||||
|
<translation>文件</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="387"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="944"/>
|
||||||
|
<source>Load</source>
|
||||||
|
<translation>加载</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="400"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="957"/>
|
||||||
|
<source>Save</source>
|
||||||
|
<translation>保存</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="420"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="534"/>
|
||||||
|
<source>Data</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="430"/>
|
||||||
|
<source>Key</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="440"/>
|
||||||
|
<source>Attack</source>
|
||||||
|
<translation>破解</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="465"/>
|
||||||
|
<source>Card Info</source>
|
||||||
|
<translation>读卡片信息</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="478"/>
|
||||||
|
<source>Check Default</source>
|
||||||
|
<translation>验证默认密码</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="491"/>
|
||||||
|
<source>Nested</source>
|
||||||
|
<translation>Nested攻击</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="498"/>
|
||||||
|
<source>Hardnested</source>
|
||||||
|
<translation>Hardested攻击</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="523"/>
|
||||||
|
<source>Read/Write</source>
|
||||||
|
<translation>读/写</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="533"/>
|
||||||
|
<source>Block:</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="565"/>
|
||||||
|
<source>Key:</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="584"/>
|
||||||
|
<source>Key Type:</source>
|
||||||
|
<translation>Key类型:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="604"/>
|
||||||
|
<source>A</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="609"/>
|
||||||
|
<source>B</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="632"/>
|
||||||
|
<source>Normal(Require Password)</source>
|
||||||
|
<translation>普通卡(需要密码)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="647"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="736"/>
|
||||||
|
<source>Read Block</source>
|
||||||
|
<translation>读单个块</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="654"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="743"/>
|
||||||
|
<source>Write Block</source>
|
||||||
|
<translation>写单个块</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="661"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="750"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="850"/>
|
||||||
|
<source>Read All</source>
|
||||||
|
<translation>读所有块</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="668"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="757"/>
|
||||||
|
<source>Write All</source>
|
||||||
|
<translation>写所有块</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="687"/>
|
||||||
|
<source>Dump</source>
|
||||||
|
<translation>Dump命令</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="700"/>
|
||||||
|
<source>Restore</source>
|
||||||
|
<translation>Restore命令</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="710"/>
|
||||||
|
<source>Chinese Magic Card(Without Password)</source>
|
||||||
|
<translation>UID卡(不需要密码)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="722"/>
|
||||||
|
<source>Lock UFUID Card</source>
|
||||||
|
<translation>锁定UFUID卡</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="729"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="461"/>
|
||||||
|
<source>About UID Card</source>
|
||||||
|
<translation>关于UID卡</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="770"/>
|
||||||
|
<source>Set Parameter</source>
|
||||||
|
<translation>设置卡参数</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="789"/>
|
||||||
|
<source>Wipe</source>
|
||||||
|
<translation>擦除</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="815"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="870"/>
|
||||||
|
<source>Simulate</source>
|
||||||
|
<translation>模拟</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="843"/>
|
||||||
|
<source>Load from data above</source>
|
||||||
|
<translation>从上方数据导入</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="413"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="863"/>
|
||||||
|
<source>Clear</source>
|
||||||
|
<translation>清空</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="893"/>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="924"/>
|
||||||
|
<source>Sniff</source>
|
||||||
|
<translation>嗅探</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="931"/>
|
||||||
|
<source>List Sniff Data</source>
|
||||||
|
<translation>列出嗅探数据</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="983"/>
|
||||||
|
<source>RawCommand</source>
|
||||||
|
<translation>原始命令</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1030"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="143"/>
|
||||||
|
<source>History:</source>
|
||||||
|
<translation>命令历史:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1062"/>
|
||||||
|
<source>ClearHistory</source>
|
||||||
|
<translation>清空历史</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1081"/>
|
||||||
|
<source>Send</source>
|
||||||
|
<translation>发送</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.ui" line="1088"/>
|
||||||
|
<source>ClearOutput</source>
|
||||||
|
<translation>清空输出</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="77"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="179"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="229"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="246"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="259"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="278"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="291"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="314"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="327"/>
|
||||||
|
<source>Info</source>
|
||||||
|
<translation>信息</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="77"/>
|
||||||
|
<source>Plz choose a port first</source>
|
||||||
|
<translation>请先选择端口</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="91"/>
|
||||||
|
<source>Connected</source>
|
||||||
|
<translation>已连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="95"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="105"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="524"/>
|
||||||
|
<source>Not Connected</source>
|
||||||
|
<translation>未连接</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>When Changeing card type, the data and keys in this app will be cleard.
|
||||||
|
Continue?</source>
|
||||||
|
<translation type="vanished">更改卡容量后,窗口中的data和key会被清空\n要继续吗?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Plz choose the data file:</source>
|
||||||
|
<translation type="vanished">请选择data文件:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="272"/>
|
||||||
|
<source>Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml);;All Files(*.*)</source>
|
||||||
|
<translation>二进制Data文件(*.bin *.dump);;文本Data文件(*.txt *.eml);;所有文件(*.*)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="278"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="291"/>
|
||||||
|
<source>Failed to open</source>
|
||||||
|
<translation>无法打开</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Plz choose the key file:</source>
|
||||||
|
<translation type="vanished">请选择key文件:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Binary Key Files(*.bin *.dump);;All Files(*.*)</source>
|
||||||
|
<translation type="vanished">二进制Key文件(*.bin *.dump);;所有文件(*.*)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Save data to</source>
|
||||||
|
<translation type="vanished">保存数据至</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="179"/>
|
||||||
|
<source>When Changeing card type, the data and keys in this app will be cleard.</source>
|
||||||
|
<translation>卡片容量改变后,上方的所有Data和Key会被清空。</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="179"/>
|
||||||
|
<source>Continue?</source>
|
||||||
|
<translation>确定?</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="208"/>
|
||||||
|
<source>Plz select the font of data widget and key widget</source>
|
||||||
|
<translation>请选择Data窗口和Key窗口的字体</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="229"/>
|
||||||
|
<source>Data must consists of 32 Hex symbols(Whitespace is allowed)</source>
|
||||||
|
<translation>Data必须由32个十六进制字符组成(中间可含有空格)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="246"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="259"/>
|
||||||
|
<source>Key must consists of 12 Hex symbols(Whitespace is allowed)</source>
|
||||||
|
<translation>Key必须由12个十六进制字符组成(中间可含有空格)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="271"/>
|
||||||
|
<source>Plz select the data file:</source>
|
||||||
|
<translation>请选择data文件:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="284"/>
|
||||||
|
<source>Plz select the key file:</source>
|
||||||
|
<translation>请选择key文件:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="285"/>
|
||||||
|
<source>Binary Key Files(*.bin *.dump);;Binary Data Files(*.bin *.dump);;All Files(*.*)</source>
|
||||||
|
<translation>二进制Key文件(*.bin *.dump)二进制Data文件(*.bin *.dump);;所有文件(*.*)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="307"/>
|
||||||
|
<source>Plz select the location to save data file:</source>
|
||||||
|
<translation>请选择文件保存的位置:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="308"/>
|
||||||
|
<source>Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml)</source>
|
||||||
|
<translation>二进制Data文件(*.bin *.dump);;文本Data文件(*.txt *.eml)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="314"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="327"/>
|
||||||
|
<source>Failed to save to</source>
|
||||||
|
<translation>无法保存至</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="320"/>
|
||||||
|
<source>Plz select the location to save key file:</source>
|
||||||
|
<translation>请选择key文件保存的位置:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="321"/>
|
||||||
|
<source>Binary Key Files(*.bin *.dump)</source>
|
||||||
|
<translation>二进制Key文件(*.bin *.dump)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="446"/>
|
||||||
|
<source> Normally, the Block 0 of a typical Mifare card, which contains the UID, is locked during the manufacture. Users cannot write anything to Block 0 or set a new UID to a normal Mifare card.</source>
|
||||||
|
<translation> 普通Mifare卡的Block0无法写入,UID也不能更改</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="447"/>
|
||||||
|
<source> Chinese Magic Cards(aka UID Cards) are some special cards whose Block 0 are writeable. And you can change UID by writing to it.</source>
|
||||||
|
<translation> UID卡(在国外叫Chinese Magic Card)的Block0可写,UID可变</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="449"/>
|
||||||
|
<source>There are two versions of Chinese Magic Cards, the Gen1 and the Gen2.</source>
|
||||||
|
<translation>国外把UID卡分为Chinese Magic Card Gen1和Gen2</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="450"/>
|
||||||
|
<source> Gen1:</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="450"/>
|
||||||
|
<source> also called UID card in China. It responses to some backdoor commands so you can access any blocks without password. The Proxmark3 has a bunch of related commands(csetblk, cgetblk, ...) to deal with this type of card, and my GUI also support these commands.</source>
|
||||||
|
<translation> 指通常所说的UID卡,可以通过后门指令直接读写块而无需密码,在PM3和此GUI中有特殊命令处理这类卡片</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="451"/>
|
||||||
|
<source> Gen2:</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="451"/>
|
||||||
|
<source> doesn't response to the backdoor commands, which means that a reader cannot detect whether it is a Chinese Magic Card or not by sending backdoor commands.</source>
|
||||||
|
<translation> 这个叫法在国内比较罕见,在国外指CUID/FUID/UFUID这类对后门指令不响应的卡(防火墙卡)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="453"/>
|
||||||
|
<source>There are some types of Chinese Magic Card Gen2.</source>
|
||||||
|
<translation>以下是Gen2卡的详细介绍</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="454"/>
|
||||||
|
<source> CUID Card:</source>
|
||||||
|
<translation> CUID卡:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="454"/>
|
||||||
|
<source> the Block 0 is writeable, you can write to this block repeatedly by normal wrbl command.</source>
|
||||||
|
<translation> 可通过普通的写块命令来写Block0,可重复擦写</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="455"/>
|
||||||
|
<source> (hf mf wrbl 0 A FFFFFFFFFFFF <the data you want to write>)</source>
|
||||||
|
<translation> (hf mf wrbl 0 A FFFFFFFFFFFF <待写入数据>)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="456"/>
|
||||||
|
<source> FUID Card:</source>
|
||||||
|
<translation> FUID卡:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="456"/>
|
||||||
|
<source> you can only write to Block 0 once. After that, it seems like a typical Mifare card(Block 0 cannot be written to).</source>
|
||||||
|
<translation> Block0只能写入一次</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="457"/>
|
||||||
|
<source> (some readers might try changing the Block 0, which could detect the CUID Card. In that case, you should use FUID card.)</source>
|
||||||
|
<translation> (更高级的穿防火墙卡,可以过一些能识别出CUID卡的读卡器)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="458"/>
|
||||||
|
<source> UFUID Card:</source>
|
||||||
|
<translation> UFUID卡:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="458"/>
|
||||||
|
<source> It behaves like a CUID card(or UID card? I'm not sure) before you send some special command to lock it. Once it is locked, you cannot change its Block 0(just like a typical Mifare card).</source>
|
||||||
|
<translation> 锁卡前和普通UID/CUID卡一样可以反复读写Block0,用特殊命令锁卡后就和FUID卡一样了</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="460"/>
|
||||||
|
<source> Seemingly, these Chinese Magic Cards are more easily to be compromised by Nested Attack(it takes little time to get an unknown key).</source>
|
||||||
|
<translation> 所有UID卡都似乎更容易被Nested攻击破解</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="525"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="642"/>
|
||||||
|
<source>Idle</source>
|
||||||
|
<translation>空闲</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="532"/>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="541"/>
|
||||||
|
<source>Sec</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="533"/>
|
||||||
|
<source>Blk</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="542"/>
|
||||||
|
<source>KeyA</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="543"/>
|
||||||
|
<source>KeyB</source>
|
||||||
|
<translation></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="579"/>
|
||||||
|
<source>HW Version:</source>
|
||||||
|
<translation>固件版本:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="581"/>
|
||||||
|
<source>PM3:</source>
|
||||||
|
<translation>连接状态:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="583"/>
|
||||||
|
<source>State:</source>
|
||||||
|
<translation>运行状态:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../ui/mainwindow.cpp" line="638"/>
|
||||||
|
<source>Running</source>
|
||||||
|
<translation>运行中</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>Mifare</name>
|
||||||
|
<message>
|
||||||
|
<source>info</source>
|
||||||
|
<translation type="vanished">信息:</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="289"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="386"/>
|
||||||
|
<source>Success!</source>
|
||||||
|
<translation>成功!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="289"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="293"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="386"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="390"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="425"/>
|
||||||
|
<source>Info</source>
|
||||||
|
<translation>信息</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="293"/>
|
||||||
|
<location filename="../module/mifare.cpp" line="390"/>
|
||||||
|
<source>Failed!</source>
|
||||||
|
<translation>失败!</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../module/mifare.cpp" line="425"/>
|
||||||
|
<source>Failed to read card.</source>
|
||||||
|
<translation>读卡失败。</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
|
</TS>
|
48
main.cpp
48
main.cpp
@ -1,11 +1,57 @@
|
|||||||
#include "mainwindow.h"
|
#include "ui/mainwindow.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
|
QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
|
||||||
|
QVariant lang = settings->value("lang", "null");
|
||||||
|
if(lang == "null")
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
lang = "lang/en_US.qm";
|
||||||
|
#else
|
||||||
|
lang = "lang/en_US.ts";
|
||||||
|
#endif
|
||||||
|
QStringList langList;
|
||||||
|
langList.append("English");
|
||||||
|
langList.append("简体中文");
|
||||||
|
QString seletedText = QInputDialog::getItem(&w, "", "Choose a language:", langList, 0, false);
|
||||||
|
if(seletedText == "English")
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
lang = "lang/en_US.qm";
|
||||||
|
#else
|
||||||
|
lang = "lang/en_US.ts";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(seletedText == "简体中文")
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
lang = "lang/zh_CN.qm";
|
||||||
|
#else
|
||||||
|
lang = "lang/zh_CN.ts";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QTranslator* translator = new QTranslator(&w);
|
||||||
|
if(translator->load(lang.toString()))
|
||||||
|
{
|
||||||
|
a.installTranslator(translator);
|
||||||
|
settings->setValue("lang", lang);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(&w, "Error", "Can't load " + lang.toString() + " as translation file.");
|
||||||
|
}
|
||||||
|
delete settings;
|
||||||
|
w.initUI();
|
||||||
w.show();
|
w.show();
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
#include "mainwindow.h"
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
|
||||||
: QMainWindow(parent)
|
|
||||||
, ui(new Ui::MainWindow)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
pm3=new PM3Process;
|
|
||||||
connect(pm3,&PM3Process::readyRead,this,&MainWindow::refresh);
|
|
||||||
connect(ui->commandEdit,&QLineEdit::editingFinished,this,&MainWindow::sendMSG);
|
|
||||||
ui->portBox->addItem("");
|
|
||||||
foreach(QString port,pm3->findPort())
|
|
||||||
{
|
|
||||||
ui->portBox->addItem(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_connectButton_clicked()
|
|
||||||
{
|
|
||||||
QString port=ui->portBox->currentText();
|
|
||||||
if(port=="")
|
|
||||||
QMessageBox::information(NULL, "Info", "Plz choose a port first", QMessageBox::Ok);
|
|
||||||
else
|
|
||||||
qDebug()<<pm3->start(ui->PM3PathEdit->text(),port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_sendButton_clicked()
|
|
||||||
{
|
|
||||||
qDebug()<<(ui->commandEdit->text().toLocal8Bit());
|
|
||||||
pm3->write((ui->commandEdit->text()+"\r\n").toLocal8Bit());
|
|
||||||
pm3->waitForBytesWritten(3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::refresh()
|
|
||||||
{
|
|
||||||
QByteArray btay=pm3->readLine();
|
|
||||||
while(btay!="")
|
|
||||||
{
|
|
||||||
qDebug()<<btay;
|
|
||||||
ui->outputEdit->insertPlainText(btay);
|
|
||||||
btay=pm3->readLine();
|
|
||||||
}
|
|
||||||
ui->outputEdit->moveCursor(QTextCursor::End);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::sendMSG()
|
|
||||||
{
|
|
||||||
if(ui->commandEdit->hasFocus())
|
|
||||||
on_sendButton_clicked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_disconnectButton_clicked()
|
|
||||||
{
|
|
||||||
pm3->kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_clearButton_clicked()
|
|
||||||
{
|
|
||||||
ui->outputEdit->clear();
|
|
||||||
}
|
|
38
mainwindow.h
38
mainwindow.h
@ -1,38 +0,0 @@
|
|||||||
#ifndef MAINWINDOW_H
|
|
||||||
#define MAINWINDOW_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include "pm3process.h"
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
namespace Ui { class MainWindow; }
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MainWindow(QWidget *parent = nullptr);
|
|
||||||
~MainWindow();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void refresh();
|
|
||||||
private slots:
|
|
||||||
void on_connectButton_clicked();
|
|
||||||
|
|
||||||
void on_sendButton_clicked();
|
|
||||||
|
|
||||||
void on_disconnectButton_clicked();
|
|
||||||
|
|
||||||
void on_clearButton_clicked();
|
|
||||||
|
|
||||||
void sendMSG();
|
|
||||||
private:
|
|
||||||
Ui::MainWindow *ui;
|
|
||||||
PM3Process* pm3;
|
|
||||||
};
|
|
||||||
#endif // MAINWINDOW_H
|
|
146
mainwindow.ui
146
mainwindow.ui
@ -1,146 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>MainWindow</class>
|
|
||||||
<widget class="QMainWindow" name="MainWindow">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>450</width>
|
|
||||||
<height>310</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>450</width>
|
|
||||||
<height>300</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Proxmark3GUI</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="centralwidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="sizeConstraint">
|
|
||||||
<enum>QLayout::SetMaximumSize</enum>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Path:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="PM3PathEdit">
|
|
||||||
<property name="text">
|
|
||||||
<string>proxmark3</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="portBox"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="connectButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Connect</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="disconnectButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Disconnect</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QTabWidget" name="funcTab">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="tab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Tab 1</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="rawTab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>RawCommand</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPlainTextEdit" name="outputEdit">
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<property name="sizeConstraint">
|
|
||||||
<enum>QLayout::SetMaximumSize</enum>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="commandEdit"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="sendButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Send</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="clearButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>ClearOutput</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenuBar" name="menubar">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>450</width>
|
|
||||||
<height>22</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
855
module/mifare.cpp
Normal file
855
module/mifare.cpp
Normal file
@ -0,0 +1,855 @@
|
|||||||
|
#include "mifare.h"
|
||||||
|
|
||||||
|
Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
this->parent = parent;
|
||||||
|
util = addr;
|
||||||
|
this->ui = ui;
|
||||||
|
cardType = card_1k;
|
||||||
|
keyAList = new QStringList();
|
||||||
|
keyBList = new QStringList();
|
||||||
|
dataList = new QStringList();
|
||||||
|
data_clearKey(); // fill with blank Qstring
|
||||||
|
data_clearData(); // fill with blank Qstring
|
||||||
|
dataPattern = new QRegExp("([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}");
|
||||||
|
chkKeyPattern = new QRegExp("\\|\\d{3}\\|.+\\|.+\\|");
|
||||||
|
nestedKeyPattern = new QRegExp("\\|\\d{3}\\|.+\\|.+\\|.+\\|.+\\|");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QString Mifare::info(bool isRequiringOutput)
|
||||||
|
{
|
||||||
|
if(isRequiringOutput)
|
||||||
|
{
|
||||||
|
QString result = util->execCMDWithOutput("hf 14a info", 500);
|
||||||
|
qDebug() << result << result.indexOf(QRegExp(ui->MF_RW_dataEdit->text()), 0);
|
||||||
|
result.replace("UID :", "|");
|
||||||
|
result.replace("ATQA :", "|");
|
||||||
|
result.replace("SAK :", "|");
|
||||||
|
result.replace("TYPE :", "|");
|
||||||
|
QStringList lis = result.split("|");
|
||||||
|
if(lis.length() > 4)
|
||||||
|
{
|
||||||
|
qDebug() << lis[1] + lis[2] + lis[3];
|
||||||
|
return lis[1] + lis[2] + lis[3];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
util->execCMD("hf 14a info");
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::chk()
|
||||||
|
{
|
||||||
|
QString result = util->execCMDWithOutput("hf mf chk *" + QString::number(cardType.type) + " ?", 1000 + cardType.type * 1000);
|
||||||
|
qDebug() << result;
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
QString tmp, tmp2;
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
offset = result.indexOf(*chkKeyPattern, offset);
|
||||||
|
tmp = result.mid(offset, 39).toUpper();
|
||||||
|
offset += 39;
|
||||||
|
qDebug() << tmp << offset;
|
||||||
|
tmp2 = tmp.mid(7, 12).trimmed();
|
||||||
|
if(tmp2 != "?")
|
||||||
|
keyAList->replace(i, tmp2);
|
||||||
|
tmp2 = tmp.mid(24, 12).trimmed();
|
||||||
|
if(tmp2 != "?")
|
||||||
|
keyBList->replace(i, tmp2);
|
||||||
|
}
|
||||||
|
data_syncWithKeyWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::nested()
|
||||||
|
{
|
||||||
|
QString result = util->execCMDWithOutput("hf mf nested " + QString::number(cardType.type) + " *");
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
QString tmp;
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
offset = result.indexOf(*nestedKeyPattern, offset);
|
||||||
|
tmp = result.mid(offset, 47).toUpper();
|
||||||
|
offset += 47;
|
||||||
|
if(tmp.at(23) == '1')
|
||||||
|
keyAList->replace(i, tmp.mid(7, 12).trimmed());
|
||||||
|
if(tmp.at(44) == '1')
|
||||||
|
keyBList->replace(i, tmp.mid(28, 12).trimmed());
|
||||||
|
}
|
||||||
|
data_syncWithKeyWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::hardnested()
|
||||||
|
{
|
||||||
|
MF_Attack_hardnestedDialog dialog(cardType.blocks);
|
||||||
|
connect(&dialog, &MF_Attack_hardnestedDialog::sendCMD, util, &Util::execCMD);
|
||||||
|
if(dialog.exec() == QDialog::Accepted)
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::sniff()
|
||||||
|
{
|
||||||
|
util->execCMD("hf mf sniff");
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::list()
|
||||||
|
{
|
||||||
|
util->execCMD("hf list mf");
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::read()
|
||||||
|
{
|
||||||
|
int waitTime = 300;
|
||||||
|
int currblk = ui->MF_RW_blockBox->currentText().toInt();
|
||||||
|
QString result = util->execCMDWithOutput("hf mf rdbl "
|
||||||
|
+ QString::number(currblk)
|
||||||
|
+ " "
|
||||||
|
+ ui->MF_RW_keyTypeBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->MF_RW_keyEdit->text(), waitTime);
|
||||||
|
if(result.indexOf("isOk:01") != -1)
|
||||||
|
{
|
||||||
|
result = result.mid(result.indexOf(*dataPattern, 0), 47).toUpper();
|
||||||
|
if((currblk < 128 && ((currblk + 1) % 4 == 0)) || ((currblk + 1) % 8 == 0)) // process key block
|
||||||
|
{
|
||||||
|
if(ui->MF_RW_keyTypeBox->currentText() == "A")
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
result = result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2));
|
||||||
|
}
|
||||||
|
ui->MF_RW_dataEdit->setText(result);
|
||||||
|
QString tmpKey = result.right(18).replace(" ", "");
|
||||||
|
result = util->execCMDWithOutput("hf mf rdbl "
|
||||||
|
+ ui->MF_RW_keyTypeBox->currentText()
|
||||||
|
+ " B "
|
||||||
|
+ tmpKey, waitTime);
|
||||||
|
if(result.indexOf("isOk:01") == -1)
|
||||||
|
{
|
||||||
|
result = ui->MF_RW_dataEdit->text();
|
||||||
|
result = result.replace(30, 17, "?? ?? ?? ?? ?? ??");
|
||||||
|
ui->MF_RW_dataEdit->setText(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
result = result.replace(30 + i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2));
|
||||||
|
}
|
||||||
|
result = result.replace(0, 18, "?? ?? ?? ?? ?? ?? ");
|
||||||
|
ui->MF_RW_dataEdit->setText(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->MF_RW_dataEdit->setText(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::readAll()
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
bool isKeyAValid;
|
||||||
|
bool isKeyBValid;
|
||||||
|
const int waitTime = 150;
|
||||||
|
|
||||||
|
QString tmp;
|
||||||
|
int offset = 0;
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
result = "";
|
||||||
|
isKeyAValid = false;
|
||||||
|
isKeyBValid = false;
|
||||||
|
|
||||||
|
// check keys and read the first block of each sector
|
||||||
|
if(data_isKeyValid(keyAList->at(i)))
|
||||||
|
{
|
||||||
|
result = util->execCMDWithOutput("hf mf rdsc "
|
||||||
|
+ QString::number(i)
|
||||||
|
+ " A "
|
||||||
|
+ keyAList->at(i), waitTime);
|
||||||
|
qDebug() << result;
|
||||||
|
offset = result.indexOf("isOk:01");
|
||||||
|
if(offset != -1)
|
||||||
|
{
|
||||||
|
isKeyAValid = true;
|
||||||
|
for(int j = 0; j < cardType.blk[i]; j++)
|
||||||
|
{
|
||||||
|
offset = result.indexOf(*dataPattern, offset);
|
||||||
|
tmp = result.mid(offset, 47).toUpper();
|
||||||
|
offset += 47;
|
||||||
|
qDebug() << tmp;
|
||||||
|
tmp.replace(" ", "");
|
||||||
|
dataList->replace(cardType.blks[i] + j, tmp);
|
||||||
|
data_syncWithDataWidget(false, cardType.blks[i] + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(data_isKeyValid(keyBList->at(i)))
|
||||||
|
{
|
||||||
|
result = util->execCMDWithOutput("hf mf rdsc "
|
||||||
|
+ QString::number(i)
|
||||||
|
+ " B "
|
||||||
|
+ keyBList->at(i), waitTime);
|
||||||
|
qDebug() << result;
|
||||||
|
offset = result.indexOf("isOk:01");
|
||||||
|
if(offset != -1)
|
||||||
|
{
|
||||||
|
isKeyBValid = true;
|
||||||
|
for(int j = 0; j < cardType.blk[i]; j++)
|
||||||
|
{
|
||||||
|
offset = result.indexOf(*dataPattern, offset);
|
||||||
|
tmp = result.mid(offset, 47).toUpper();
|
||||||
|
offset += 47;
|
||||||
|
qDebug() << tmp;
|
||||||
|
tmp.replace(" ", "");
|
||||||
|
dataList->replace(cardType.blks[i] + j, tmp);
|
||||||
|
data_syncWithDataWidget(false, cardType.blks[i] + j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isKeyAValid || isKeyBValid)
|
||||||
|
{
|
||||||
|
|
||||||
|
// fill the MF_dataWidget with the known valid key
|
||||||
|
//
|
||||||
|
// check whether the MF_dataWidget contains the valid key,
|
||||||
|
// and fill MF_keyWidget(when you only have KeyA but the ReadBlock output contains the KeyB)
|
||||||
|
//
|
||||||
|
// the structure is not symmetric, since you cannot get KeyA from output
|
||||||
|
// this program will only process the provided KeyA(in MF_keyWidget)
|
||||||
|
result = dataList->at(cardType.blks[i] + cardType.blk[i] - 1);
|
||||||
|
if(isKeyAValid)
|
||||||
|
{
|
||||||
|
result.replace(0, 12, keyAList->at(i));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = result.replace(0, 12, "????????????");
|
||||||
|
}
|
||||||
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result);
|
||||||
|
|
||||||
|
if(isKeyBValid)
|
||||||
|
{
|
||||||
|
result.replace(20, 12, keyBList->at(i));
|
||||||
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result);
|
||||||
|
data_syncWithDataWidget(false, cardType.blks[i] + cardType.blk[i] - 1);
|
||||||
|
}
|
||||||
|
else // now isKeyAValid == true, the output might contains the KeyB
|
||||||
|
{
|
||||||
|
QString tmpKey = dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12);
|
||||||
|
result = util->execCMDWithOutput("hf mf rdbl "
|
||||||
|
+ QString::number(cardType.blks[i] + cardType.blk[i] - 1)
|
||||||
|
+ " B "
|
||||||
|
+ tmpKey, waitTime);
|
||||||
|
if(result.indexOf("isOk:01") != -1)
|
||||||
|
{
|
||||||
|
keyBList->replace(i, tmpKey);
|
||||||
|
data_syncWithKeyWidget(false, i, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = dataList->at(cardType.blks[i] + cardType.blk[i] - 1);
|
||||||
|
result = result.replace(20, 12, "????????????");
|
||||||
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, result);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data_syncWithDataWidget(false, cardType.blks[i] + cardType.blk[i] - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::write()
|
||||||
|
{
|
||||||
|
int waitTime = 300;
|
||||||
|
QString result = util->execCMDWithOutput("hf mf wrbl "
|
||||||
|
+ ui->MF_RW_blockBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->MF_RW_keyTypeBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->MF_RW_keyEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->MF_RW_dataEdit->text().replace(" ", ""), waitTime);
|
||||||
|
if(result.indexOf("isOk:01") != -1)
|
||||||
|
{
|
||||||
|
QMessageBox::information(parent, tr("Info"), tr("Success!"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(parent, tr("Info"), tr("Failed!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::writeAll()
|
||||||
|
{
|
||||||
|
const int waitTime = 300;
|
||||||
|
QString result;
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < cardType.blk[i]; j++)
|
||||||
|
{
|
||||||
|
result = ""; // if the KeyA is invalid and the result is not empty, the KeyB will not be tested.
|
||||||
|
if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?'))
|
||||||
|
continue;
|
||||||
|
if(data_isKeyValid(keyAList->at(i)))
|
||||||
|
{
|
||||||
|
result = util->execCMDWithOutput("hf mf wrbl "
|
||||||
|
+ QString::number(cardType.blks[i] + j)
|
||||||
|
+ " A "
|
||||||
|
+ keyAList->at(i)
|
||||||
|
+ " "
|
||||||
|
+ dataList->at(cardType.blks[i] + j), waitTime);
|
||||||
|
}
|
||||||
|
qDebug() << i << j << result.indexOf("isOk:01") << data_isKeyValid(keyBList->at(i));
|
||||||
|
if(result.indexOf("isOk:01") == -1 && data_isKeyValid(keyBList->at(i)))
|
||||||
|
{
|
||||||
|
result = util->execCMDWithOutput("hf mf wrbl "
|
||||||
|
+ QString::number(cardType.blks[i] + j)
|
||||||
|
+ " B "
|
||||||
|
+ keyBList->at(i)
|
||||||
|
+ " "
|
||||||
|
+ dataList->at(cardType.blks[i] + j), waitTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::readC()
|
||||||
|
{
|
||||||
|
int waitTime = 300;
|
||||||
|
int currblk = ui->MF_RW_blockBox->currentText().toInt();
|
||||||
|
QString result = util->execCMDWithOutput("hf mf cgetblk "
|
||||||
|
+ QString::number(currblk), waitTime);
|
||||||
|
if(result.indexOf("No chinese") == -1)
|
||||||
|
{
|
||||||
|
result = result.mid(result.indexOf(*dataPattern, 0), 47).toUpper();
|
||||||
|
ui->MF_RW_dataEdit->setText(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::readAllC()
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
const int waitTime = 150;
|
||||||
|
|
||||||
|
QString tmp;
|
||||||
|
int offset = 0;
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
result = util->execCMDWithOutput("hf mf cgetsc "
|
||||||
|
+ QString::number(i), waitTime);
|
||||||
|
qDebug() << result;
|
||||||
|
if(result.indexOf("No chinese") == -1)
|
||||||
|
{
|
||||||
|
offset = 0;
|
||||||
|
for(int j = 0; j < cardType.blk[i]; j++)
|
||||||
|
{
|
||||||
|
offset = result.indexOf(*dataPattern, offset);
|
||||||
|
tmp = result.mid(offset, 47).toUpper();
|
||||||
|
offset += 47;
|
||||||
|
qDebug() << tmp;
|
||||||
|
tmp.replace(" ", "");
|
||||||
|
dataList->replace(cardType.blks[i] + j, tmp);
|
||||||
|
data_syncWithDataWidget(false, cardType.blks[i] + j);
|
||||||
|
}
|
||||||
|
keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12));
|
||||||
|
keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12));
|
||||||
|
data_syncWithKeyWidget(false, i, true);
|
||||||
|
data_syncWithKeyWidget(false, i, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::writeC()
|
||||||
|
{
|
||||||
|
int waitTime = 150;
|
||||||
|
QString result = util->execCMDWithOutput("hf mf csetblk "
|
||||||
|
+ ui->MF_RW_blockBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->MF_RW_dataEdit->text().replace(" ", ""), waitTime);
|
||||||
|
if(result.indexOf("No chinese") == -1)
|
||||||
|
{
|
||||||
|
QMessageBox::information(parent, tr("Info"), tr("Success!"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(parent, tr("Info"), tr("Failed!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::writeAllC()
|
||||||
|
{
|
||||||
|
const int waitTime = 150;
|
||||||
|
QString result;
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < cardType.blk[i]; j++)
|
||||||
|
{
|
||||||
|
result = ""; // if the KeyA is invalid and the result is not empty, the KeyB will not be tested.
|
||||||
|
if(data_isDataValid(dataList->at(cardType.blks[i] + j)) != DATA_NOSPACE || dataList->at(cardType.blks[i] + j).contains('?'))
|
||||||
|
continue;
|
||||||
|
result = util->execCMDWithOutput("hf mf csetblk "
|
||||||
|
+ QString::number(cardType.blks[i] + j)
|
||||||
|
+ " "
|
||||||
|
+ dataList->at(cardType.blks[i] + j), waitTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::wipeC()
|
||||||
|
{
|
||||||
|
util->execCMD("hf mf cwipe "
|
||||||
|
+ QString::number(cardType.type)
|
||||||
|
+ " f");
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::setParameterC()
|
||||||
|
{
|
||||||
|
QString result = info(true);
|
||||||
|
if(result == "")
|
||||||
|
QMessageBox::information(parent, tr("Info"), tr("Failed to read card."));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QStringList lis = result.split("\r\n");
|
||||||
|
lis[0].replace(" ", "");
|
||||||
|
lis[1].replace(" ", "");
|
||||||
|
lis[2].replace(" ", "");
|
||||||
|
MF_UID_parameterDialog dialog(lis[0].toUpper(), lis[1].toUpper(), lis[2].mid(0, 2).toUpper());
|
||||||
|
connect(&dialog, &MF_UID_parameterDialog::sendCMD, util, &Util::execCMD);
|
||||||
|
if(dialog.exec() == QDialog::Accepted)
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::lockC()
|
||||||
|
{
|
||||||
|
util->execCMD("hf 14a raw -pa -b7 40");
|
||||||
|
util->execCMD("hf 14a raw -pa 43");
|
||||||
|
util->execCMD("hf 14a raw -pa E0 00 39 F7");
|
||||||
|
util->execCMD("hf 14a raw -pa E1 00 E1 EE");
|
||||||
|
util->execCMD("hf 14a raw -pa 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 18 47");
|
||||||
|
util->execCMD("hf 14a raw 52");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::dump()
|
||||||
|
{
|
||||||
|
util->execCMD("hf mf dump");
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::restore()
|
||||||
|
{
|
||||||
|
util->execCMD("hf mf restore");
|
||||||
|
ui->funcTab->setCurrentIndex(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_syncWithDataWidget(bool syncAll, int block)
|
||||||
|
{
|
||||||
|
QString tmp;
|
||||||
|
if(syncAll)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.blocks; i++)
|
||||||
|
{
|
||||||
|
tmp = "";
|
||||||
|
if(dataList->at(i) != "")
|
||||||
|
{
|
||||||
|
tmp += dataList->at(i).mid(0, 2);
|
||||||
|
for(int j = 1; j < 16; j++)
|
||||||
|
{
|
||||||
|
tmp += " ";
|
||||||
|
tmp += dataList->at(i).mid(j * 2, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->MF_dataWidget->item(i, 2)->setText(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp = "";
|
||||||
|
if(dataList->at(block) != "")
|
||||||
|
{
|
||||||
|
tmp += dataList->at(block).mid(0, 2);
|
||||||
|
for(int j = 1; j < 16; j++)
|
||||||
|
{
|
||||||
|
tmp += " ";
|
||||||
|
tmp += dataList->at(block).mid(j * 2, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->MF_dataWidget->item(block, 2)->setText(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_syncWithKeyWidget(bool syncAll, int sector, bool isKeyA)
|
||||||
|
{
|
||||||
|
if(syncAll)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
ui->MF_keyWidget->item(i, 1)->setText(keyAList->at(i));
|
||||||
|
ui->MF_keyWidget->item(i, 2)->setText(keyBList->at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(isKeyA)
|
||||||
|
ui->MF_keyWidget->item(sector, 1)->setText(keyAList->at(sector));
|
||||||
|
else
|
||||||
|
ui->MF_keyWidget->item(sector, 2)->setText(keyBList->at(sector));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_clearData()
|
||||||
|
{
|
||||||
|
dataList->clear();
|
||||||
|
for(int i = 0; i < cardType.blocks; i++)
|
||||||
|
dataList->append("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_clearKey()
|
||||||
|
{
|
||||||
|
keyAList->clear();
|
||||||
|
keyBList->clear();
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
keyAList->append("");
|
||||||
|
keyBList->append("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mifare::data_isKeyValid(const QString& key)
|
||||||
|
{
|
||||||
|
if(key.length() != 12)
|
||||||
|
return false;
|
||||||
|
for(int i = 0; i < 12; i++)
|
||||||
|
{
|
||||||
|
if(!((key[i] >= '0' && key[i] <= '9') || (key[i] >= 'A' && key[i] <= 'F')))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mifare::DataType Mifare::data_isDataValid(QString data) // "?" will not been processd there
|
||||||
|
{
|
||||||
|
if(data.length() == 47)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 47; i++)
|
||||||
|
{
|
||||||
|
if(i % 3 != 0)
|
||||||
|
{
|
||||||
|
if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
|
||||||
|
return DATA_INVALID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(data[i] != ' ')
|
||||||
|
return DATA_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DATA_WITHSPACE;
|
||||||
|
}
|
||||||
|
else if(data.length() == 32)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
if(!((data[i] >= '0' && data[i] <= '9') || (data[i] >= 'A' && data[i] <= 'F') || data[i] == '?'))
|
||||||
|
return DATA_INVALID;
|
||||||
|
}
|
||||||
|
return DATA_NOSPACE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return DATA_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mifare::CardType Mifare::getCardType()
|
||||||
|
{
|
||||||
|
return cardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::setCardType(int type)
|
||||||
|
{
|
||||||
|
if(type == 0 || type == 1 || type == 2 || type == 4)
|
||||||
|
{
|
||||||
|
if(type == 0)
|
||||||
|
cardType = card_mini;
|
||||||
|
else if(type == 1)
|
||||||
|
cardType = card_1k;
|
||||||
|
else if(type == 2)
|
||||||
|
cardType = card_2k;
|
||||||
|
else if(type == 4)
|
||||||
|
cardType = card_4k;
|
||||||
|
data_clearKey();
|
||||||
|
data_clearData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mifare::data_loadDataFile(const QString& filename)
|
||||||
|
{
|
||||||
|
QFile file(filename, this);
|
||||||
|
if(file.open(QIODevice::ReadOnly))
|
||||||
|
{
|
||||||
|
QByteArray buff;
|
||||||
|
buff = file.read(10000);
|
||||||
|
bool isBin = false;
|
||||||
|
for(int i = 0; i < cardType.blocks * 16; i++) // Detect the file type
|
||||||
|
{
|
||||||
|
// qDebug() << (unsigned char)buff[i];
|
||||||
|
if(!((buff[i] >= 'A' && buff[i] <= 'F') ||
|
||||||
|
(buff[i] >= 'a' && buff[i] <= 'f') ||
|
||||||
|
(buff[i] >= '0' && buff[i] <= '9') ||
|
||||||
|
buff[i] == '\n' ||
|
||||||
|
buff[i] == '\r'))
|
||||||
|
{
|
||||||
|
isBin = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isBin)
|
||||||
|
{
|
||||||
|
if(file.size() < cardType.blocks * 16)
|
||||||
|
return false;
|
||||||
|
for(int i = 0; i < cardType.blocks; i++)
|
||||||
|
{
|
||||||
|
QString tmp = bin2text(buff, i, 16);
|
||||||
|
dataList->replace(i, tmp.toUpper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString tmp = buff.left(cardType.blocks * 34);
|
||||||
|
QStringList tmpList = tmp.split("\r\n");
|
||||||
|
for(int i = 0; i < cardType.blocks; i++)
|
||||||
|
{
|
||||||
|
dataList->replace(i, tmpList[i].toUpper());
|
||||||
|
qDebug() << tmpList[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
data_syncWithDataWidget();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mifare::data_loadKeyFile(const QString& filename)
|
||||||
|
{
|
||||||
|
QFile file(filename, this);
|
||||||
|
if(file.open(QIODevice::ReadOnly))
|
||||||
|
{
|
||||||
|
QByteArray buff;
|
||||||
|
buff = file.read(10000);
|
||||||
|
bool isKey = file.size() <= cardType.sectors * 14;
|
||||||
|
if(isKey)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
QString tmp = bin2text(buff, i, 12);
|
||||||
|
keyAList->replace(i, tmp.left(12).toUpper());
|
||||||
|
keyBList->replace(i, tmp.right(12).toUpper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
int blk = cardType.blks[i] + cardType.blk[i] - 1;
|
||||||
|
QString tmp = bin2text(buff, blk, 16);
|
||||||
|
keyAList->replace(i, tmp.left(12).toUpper());
|
||||||
|
keyBList->replace(i, tmp.right(12).toUpper());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
data_syncWithKeyWidget();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Mifare::bin2text(const QByteArray& buff, int i, int length)
|
||||||
|
{
|
||||||
|
QString ret = "";
|
||||||
|
char LByte, RByte;
|
||||||
|
char map[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||||
|
for(int j = 0; j < length; j++)
|
||||||
|
{
|
||||||
|
LByte = map[(unsigned char)buff[i * length + j] >> 4];
|
||||||
|
RByte = map[(unsigned char)buff[i * length + j] & 0xF];
|
||||||
|
ret += LByte;
|
||||||
|
ret += RByte;
|
||||||
|
}
|
||||||
|
qDebug() << ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mifare::data_saveDataFile(const QString& filename, bool isBin)
|
||||||
|
{
|
||||||
|
QFile file(filename, this);
|
||||||
|
if(file.open(QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
QByteArray buff;
|
||||||
|
QChar tmp;
|
||||||
|
if(isBin)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.blocks; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
unsigned char Byt[2];
|
||||||
|
for(int k = 0; k < 2; k++)
|
||||||
|
{
|
||||||
|
tmp = dataList->at(i).at(j * 2 + k).toUpper();
|
||||||
|
if(tmp >= '0' && tmp <= '9')
|
||||||
|
Byt[k] = tmp.toLatin1() - '0';
|
||||||
|
else if(tmp >= 'A' && tmp <= 'F')
|
||||||
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
||||||
|
}
|
||||||
|
buff += (Byt[0] << 4) | Byt[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.blocks; i++)
|
||||||
|
{
|
||||||
|
buff += dataList->at(i);
|
||||||
|
buff += "\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool ret = file.write(buff) != -1;
|
||||||
|
file.close();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Mifare::data_saveKeyFile(const QString& filename, bool isBin)
|
||||||
|
{
|
||||||
|
QFile file(filename, this);
|
||||||
|
if(file.open(QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
QByteArray buff;
|
||||||
|
QChar tmp;
|
||||||
|
if(isBin)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < 6; j++)
|
||||||
|
{
|
||||||
|
unsigned char Byt[2];
|
||||||
|
for(int k = 0; k < 2; k++)
|
||||||
|
{
|
||||||
|
tmp = keyAList->at(i).at(j * 2 + k).toUpper();
|
||||||
|
if(tmp >= '0' && tmp <= '9')
|
||||||
|
Byt[k] = tmp.toLatin1() - '0';
|
||||||
|
else if(tmp >= 'A' && tmp <= 'F')
|
||||||
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
||||||
|
}
|
||||||
|
buff += (Byt[0] << 4) | Byt[1];
|
||||||
|
}
|
||||||
|
for(int j = 0; j < 6; j++)
|
||||||
|
{
|
||||||
|
unsigned char Byt[2];
|
||||||
|
for(int k = 0; k < 2; k++)
|
||||||
|
{
|
||||||
|
tmp = keyBList->at(i).at(j * 2 + k).toUpper();
|
||||||
|
if(tmp >= '0' && tmp <= '9')
|
||||||
|
Byt[k] = tmp.toLatin1() - '0';
|
||||||
|
else if(tmp >= 'A' && tmp <= 'F')
|
||||||
|
Byt[k] = tmp.toLatin1() - 'A' + 10;
|
||||||
|
}
|
||||||
|
buff += (Byt[0] << 4) | Byt[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
bool ret = file.write(buff) != -1;
|
||||||
|
file.close();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_key2Data()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
QString tmp = "";
|
||||||
|
if(data_isKeyValid(keyAList->at(i)))
|
||||||
|
tmp += keyAList->at(i);
|
||||||
|
else
|
||||||
|
tmp += "????????????";
|
||||||
|
|
||||||
|
if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "")
|
||||||
|
tmp += "FF078069"; // default control bytes
|
||||||
|
else
|
||||||
|
tmp += dataList->at(cardType.blks[i] + cardType.blk[i] - 1).mid(12, 8);
|
||||||
|
|
||||||
|
if(data_isKeyValid(keyBList->at(i)))
|
||||||
|
tmp += keyBList->at(i);
|
||||||
|
else
|
||||||
|
tmp += "????????????";
|
||||||
|
|
||||||
|
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, tmp);
|
||||||
|
data_syncWithDataWidget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_data2Key()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < cardType.sectors; i++)
|
||||||
|
{
|
||||||
|
if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "")
|
||||||
|
{
|
||||||
|
keyAList->replace(i, "????????????");
|
||||||
|
keyBList->replace(i, "????????????");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12));
|
||||||
|
keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12));
|
||||||
|
}
|
||||||
|
data_syncWithKeyWidget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_setData(int block, const QString& data)
|
||||||
|
{
|
||||||
|
dataList->replace(block, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare::data_setKey(int sector, bool isKeyA, const QString& key)
|
||||||
|
{
|
||||||
|
if(isKeyA)
|
||||||
|
keyAList->replace(sector, key);
|
||||||
|
else
|
||||||
|
keyBList->replace(sector, key);
|
||||||
|
}
|
126
module/mifare.h
Normal file
126
module/mifare.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#ifndef MIFARE_H
|
||||||
|
#define MIFARE_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include "ui/mf_attack_hardnesteddialog.h"
|
||||||
|
#include "ui/mf_uid_parameterdialog.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QMessageBox>
|
||||||
|
class Mifare : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
QString info(bool isRequiringOutput = false);
|
||||||
|
void chk();
|
||||||
|
void nested();
|
||||||
|
void hardnested();
|
||||||
|
void sniff();
|
||||||
|
void list();
|
||||||
|
void read();
|
||||||
|
void readAll();
|
||||||
|
void write();
|
||||||
|
void writeAll();
|
||||||
|
void dump();
|
||||||
|
void restore();
|
||||||
|
|
||||||
|
enum DataType
|
||||||
|
{
|
||||||
|
DATA_INVALID,
|
||||||
|
DATA_WITHSPACE,
|
||||||
|
DATA_NOSPACE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CardType
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
int sectors;
|
||||||
|
int blocks;
|
||||||
|
int blk[40];
|
||||||
|
int blks[40];
|
||||||
|
};
|
||||||
|
|
||||||
|
const CardType card_mini =
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
20,
|
||||||
|
{4, 4, 4, 4, 4},
|
||||||
|
{0, 4, 8, 12, 16}
|
||||||
|
};
|
||||||
|
const CardType card_1k =
|
||||||
|
{
|
||||||
|
1,
|
||||||
|
16,
|
||||||
|
64,
|
||||||
|
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||||
|
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60}
|
||||||
|
};
|
||||||
|
const CardType card_2k =
|
||||||
|
{
|
||||||
|
2,
|
||||||
|
32,
|
||||||
|
128,
|
||||||
|
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
||||||
|
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124}
|
||||||
|
};
|
||||||
|
const CardType card_4k =
|
||||||
|
{
|
||||||
|
4,
|
||||||
|
40,
|
||||||
|
256,
|
||||||
|
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 16},
|
||||||
|
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 144, 160, 176, 192, 208, 224, 240}
|
||||||
|
};
|
||||||
|
|
||||||
|
void data_clearData();
|
||||||
|
void data_clearKey();
|
||||||
|
bool data_isKeyValid(const QString &key);
|
||||||
|
Mifare::DataType data_isDataValid(QString data);
|
||||||
|
void data_syncWithDataWidget(bool syncAll = true, int block = 0);
|
||||||
|
void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, bool isKeyA = true);
|
||||||
|
|
||||||
|
CardType cardType;
|
||||||
|
Mifare::CardType getCardType();
|
||||||
|
void setCardType(int type);
|
||||||
|
void writeAllC();
|
||||||
|
void writeC();
|
||||||
|
void readAllC();
|
||||||
|
void readC();
|
||||||
|
void wipeC();
|
||||||
|
void setParameterC();
|
||||||
|
|
||||||
|
bool data_loadDataFile(const QString &filename);
|
||||||
|
bool data_loadKeyFile(const QString &filename);
|
||||||
|
bool data_saveDataFile(const QString& filename, bool isBin);
|
||||||
|
bool data_saveKeyFile(const QString &filename, bool isBin);
|
||||||
|
void data_key2Data();
|
||||||
|
void data_data2Key();
|
||||||
|
|
||||||
|
void data_setData(int block, const QString &data);
|
||||||
|
void data_setKey(int sector, bool isKeyA, const QString &key);
|
||||||
|
void lockC();
|
||||||
|
public slots:
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget* parent;
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
Util* util;
|
||||||
|
|
||||||
|
QStringList* keyAList;
|
||||||
|
QStringList* keyBList;
|
||||||
|
QStringList* dataList;
|
||||||
|
QRegExp* dataPattern;
|
||||||
|
QRegExp* chkKeyPattern;
|
||||||
|
QRegExp* nestedKeyPattern;
|
||||||
|
QRegExp* UIDPattern;
|
||||||
|
QString bin2text(const QByteArray &buff, int start, int length);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIFARE_H
|
@ -1,29 +0,0 @@
|
|||||||
#include "pm3process.h"
|
|
||||||
|
|
||||||
PM3Process::PM3Process(QObject* parent): QProcess(parent)
|
|
||||||
{
|
|
||||||
setProcessChannelMode(PM3Process::MergedChannels);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList PM3Process::findPort()
|
|
||||||
{
|
|
||||||
QSerialPort serial;
|
|
||||||
QStringList retList;
|
|
||||||
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
|
||||||
{
|
|
||||||
serial.setPort(info);
|
|
||||||
if(serial.open(QIODevice::ReadWrite))
|
|
||||||
{
|
|
||||||
retList<<info.portName();
|
|
||||||
serial.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retList;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PM3Process::start(const QString path, const QString port)
|
|
||||||
{
|
|
||||||
// using "-f" option to make the client output flushed after every print.
|
|
||||||
QProcess::start(path, QStringList()<<port<<"-f",QProcess::Unbuffered|QProcess::ReadWrite);
|
|
||||||
return waitForStarted();
|
|
||||||
}
|
|
19
pm3process.h
19
pm3process.h
@ -1,19 +0,0 @@
|
|||||||
#ifndef PM3PROCESS_H
|
|
||||||
#define PM3PROCESS_H
|
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QString>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QtSerialPort/QSerialPortInfo>
|
|
||||||
#include <QtSerialPort/QSerialPort>
|
|
||||||
|
|
||||||
class PM3Process : public QProcess
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PM3Process(QObject* parent=nullptr);
|
|
||||||
bool start(const QString path, const QString port);
|
|
||||||
QStringList findPort();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PM3PROCESS_H
|
|
653
ui/mainwindow.cpp
Normal file
653
ui/mainwindow.cpp
Normal file
@ -0,0 +1,653 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
, ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->MF_simGroupBox->setVisible(false); // developing...
|
||||||
|
ui->MF_sniffGroupBox->setVisible(false); // developing...
|
||||||
|
myInfo = new QAction("wh201906", this);
|
||||||
|
connect(myInfo, &QAction::triggered, [ = ]() {
|
||||||
|
QDesktopServices::openUrl(QUrl("https://github.com/wh201906"));
|
||||||
|
});
|
||||||
|
this->addAction(myInfo);
|
||||||
|
|
||||||
|
pm3Thread = new QThread(this);
|
||||||
|
pm3 = new PM3Process(pm3Thread);
|
||||||
|
// pm3->moveToThread(pm3Thread);
|
||||||
|
// pm3->init();
|
||||||
|
pm3Thread->start();
|
||||||
|
pm3state = false;
|
||||||
|
|
||||||
|
util = new Util(this);
|
||||||
|
mifare = new Mifare(ui, util, this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
emit killPM3();
|
||||||
|
pm3Thread->exit(0);
|
||||||
|
pm3Thread->wait(5000);
|
||||||
|
delete pm3;
|
||||||
|
delete pm3Thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::initUI() // will be called by main.app
|
||||||
|
{
|
||||||
|
ui->retranslateUi(this);
|
||||||
|
uiInit();
|
||||||
|
signalInit();
|
||||||
|
setState(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ******************** basic functions ********************
|
||||||
|
|
||||||
|
void MainWindow::on_PM3_refreshPortButton_clicked()
|
||||||
|
{
|
||||||
|
ui->PM3_portBox->clear();
|
||||||
|
ui->PM3_portBox->addItem("");
|
||||||
|
QSerialPort serial;
|
||||||
|
QStringList serialList;
|
||||||
|
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
||||||
|
{
|
||||||
|
qDebug() << info.isBusy() << info.isNull() << info.portName();
|
||||||
|
serial.setPort(info);
|
||||||
|
|
||||||
|
if(serial.open(QIODevice::ReadWrite))
|
||||||
|
{
|
||||||
|
serialList << info.portName();
|
||||||
|
serial.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach(QString port, serialList)
|
||||||
|
{
|
||||||
|
ui->PM3_portBox->addItem(port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_PM3_connectButton_clicked()
|
||||||
|
{
|
||||||
|
qDebug() << "Main:" << QThread::currentThread();
|
||||||
|
QString port = ui->PM3_portBox->currentText();
|
||||||
|
if(port == "")
|
||||||
|
QMessageBox::information(NULL, tr("Info"), tr("Plz choose a port first"), QMessageBox::Ok);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit connectPM3(ui->PM3_pathEdit->text(), port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onPM3StateChanged(bool st, QString info)
|
||||||
|
{
|
||||||
|
pm3state = st;
|
||||||
|
setState(st);
|
||||||
|
if(st == true)
|
||||||
|
{
|
||||||
|
setStatusBar(PM3VersionBar, info);
|
||||||
|
setStatusBar(connectStatusBar, tr("Connected"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setStatusBar(connectStatusBar, tr("Not Connected"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_PM3_disconnectButton_clicked()
|
||||||
|
{
|
||||||
|
pm3state = false;
|
||||||
|
setState(false);
|
||||||
|
emit killPM3();
|
||||||
|
emit setSerialListener("", false);
|
||||||
|
setStatusBar(connectStatusBar, tr("Not Connected"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::refreshOutput(const QString& output)
|
||||||
|
{
|
||||||
|
// qDebug() << "MainWindow::refresh:" << output;
|
||||||
|
ui->Raw_outputEdit->insertPlainText(output);
|
||||||
|
ui->Raw_outputEdit->moveCursor(QTextCursor::End);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::refreshCMD(const QString& cmd)
|
||||||
|
{
|
||||||
|
ui->Raw_CMDEdit->setText(cmd);
|
||||||
|
if(cmd != "" && (ui->Raw_CMDHistoryWidget->count() == 0 || ui->Raw_CMDHistoryWidget->item(ui->Raw_CMDHistoryWidget->count() - 1)->text() != cmd))
|
||||||
|
ui->Raw_CMDHistoryWidget->addItem(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *********************************************************
|
||||||
|
|
||||||
|
// ******************** raw command ********************
|
||||||
|
|
||||||
|
void MainWindow::on_Raw_sendCMDButton_clicked()
|
||||||
|
{
|
||||||
|
util->execCMD(ui->Raw_CMDEdit->text());
|
||||||
|
refreshCMD(ui->Raw_CMDEdit->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_Raw_clearOutputButton_clicked()
|
||||||
|
{
|
||||||
|
ui->Raw_outputEdit->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_Raw_CMDHistoryBox_stateChanged(int arg1)
|
||||||
|
{
|
||||||
|
if(arg1 == Qt::Checked)
|
||||||
|
{
|
||||||
|
ui->Raw_CMDHistoryWidget->setVisible(true);
|
||||||
|
ui->Raw_clearHistoryButton->setVisible(true);
|
||||||
|
ui->Raw_CMDHistoryBox->setText(tr("History:"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->Raw_CMDHistoryWidget->setVisible(false);
|
||||||
|
ui->Raw_clearHistoryButton->setVisible(false);
|
||||||
|
ui->Raw_CMDHistoryBox->setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_Raw_clearHistoryButton_clicked()
|
||||||
|
{
|
||||||
|
ui->Raw_CMDHistoryWidget->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_Raw_CMDHistoryWidget_itemDoubleClicked(QListWidgetItem *item)
|
||||||
|
{
|
||||||
|
ui->Raw_CMDEdit->setText(item->text());
|
||||||
|
ui->Raw_CMDEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::sendMSG() // send command when pressing Enter
|
||||||
|
{
|
||||||
|
if(ui->Raw_CMDEdit->hasFocus())
|
||||||
|
on_Raw_sendCMDButton_clicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *****************************************************
|
||||||
|
|
||||||
|
// ******************** mifare ********************
|
||||||
|
void MainWindow::MF_onTypeChanged(int id, bool st)
|
||||||
|
{
|
||||||
|
typeBtnGroup->blockSignals(true);
|
||||||
|
qDebug() << id << typeBtnGroup->checkedId();
|
||||||
|
if(!st)
|
||||||
|
{
|
||||||
|
int result = QMessageBox::question(this, tr("Info"), tr("When Changeing card type, the data and keys in this app will be cleard.") + "\n" + tr("Continue?"), QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if(result == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
qDebug() << "Yes";
|
||||||
|
mifare->setCardType(typeBtnGroup->checkedId());
|
||||||
|
MF_widgetReset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "No";
|
||||||
|
typeBtnGroup->button(id)->setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
typeBtnGroup->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_data2KeyBotton_clicked()
|
||||||
|
{
|
||||||
|
mifare->data_data2Key();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_key2DataBotton_clicked()
|
||||||
|
{
|
||||||
|
mifare->data_key2Data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_fontButton_clicked()
|
||||||
|
{
|
||||||
|
bool isOK = false;
|
||||||
|
QFont font = QFontDialog::getFont(&isOK, ui->MF_keyWidget->font(), this, tr("Plz select the font of data widget and key widget"));
|
||||||
|
|
||||||
|
if(isOK)
|
||||||
|
{
|
||||||
|
ui->MF_keyWidget->setFont(font);
|
||||||
|
ui->MF_dataWidget->setFont(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(item->column() == 2)
|
||||||
|
{
|
||||||
|
QString data = item->text().replace(" ", "").toUpper();
|
||||||
|
if(data == "" || mifare->data_isDataValid(data) == Mifare::DATA_NOSPACE)
|
||||||
|
{
|
||||||
|
mifare->data_setData(item->row(), data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Info"), tr("Data must consists of 32 Hex symbols(Whitespace is allowed)"));
|
||||||
|
}
|
||||||
|
mifare->data_syncWithDataWidget(false, item->row());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item)
|
||||||
|
{
|
||||||
|
if(item->column() == 1)
|
||||||
|
{
|
||||||
|
QString key = item->text().replace(" ", "").toUpper();
|
||||||
|
if(key == "" || mifare->data_isKeyValid(key))
|
||||||
|
{
|
||||||
|
mifare->data_setKey(item->row(), true, key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)"));
|
||||||
|
}
|
||||||
|
mifare->data_syncWithKeyWidget(false, item->row(), true);
|
||||||
|
}
|
||||||
|
else if(item->column() == 2)
|
||||||
|
{
|
||||||
|
QString key = item->text().replace(" ", "");
|
||||||
|
if(key == "" || mifare->data_isKeyValid(key))
|
||||||
|
{
|
||||||
|
mifare->data_setKey(item->row(), false, key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)"));
|
||||||
|
}
|
||||||
|
mifare->data_syncWithKeyWidget(false, item->row(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_File_loadButton_clicked()
|
||||||
|
{
|
||||||
|
QString title = "";
|
||||||
|
QString filename = "";
|
||||||
|
if(ui->MF_File_dataBox->isChecked())
|
||||||
|
{
|
||||||
|
title = tr("Plz select the data file:");
|
||||||
|
filename = QFileDialog::getOpenFileName(this, title, "./", tr("Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml);;All Files(*.*)"));
|
||||||
|
qDebug() << filename;
|
||||||
|
if(filename != "")
|
||||||
|
{
|
||||||
|
if(!mifare->data_loadDataFile(filename))
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Info"), tr("Failed to open") + "\n" + filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ui->MF_File_keyBox->isChecked())
|
||||||
|
{
|
||||||
|
title = tr("Plz select the key file:");
|
||||||
|
filename = QFileDialog::getOpenFileName(this, title, "./", tr("Binary Key Files(*.bin *.dump);;Binary Data Files(*.bin *.dump);;All Files(*.*)"));
|
||||||
|
qDebug() << filename;
|
||||||
|
if(filename != "")
|
||||||
|
{
|
||||||
|
if(!mifare->data_loadKeyFile(filename))
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Info"), tr("Failed to open") + "\n" + filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_File_saveButton_clicked()
|
||||||
|
{
|
||||||
|
|
||||||
|
QString title = "";
|
||||||
|
QString filename = "";
|
||||||
|
QString selectedType = "";
|
||||||
|
|
||||||
|
if(ui->MF_File_dataBox->isChecked())
|
||||||
|
{
|
||||||
|
title = tr("Plz select the location to save data file:");
|
||||||
|
filename = QFileDialog::getSaveFileName(this, title, "./", tr("Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml)"), &selectedType);
|
||||||
|
qDebug() << filename;
|
||||||
|
if(filename != "")
|
||||||
|
{
|
||||||
|
if(!mifare->data_saveDataFile(filename, selectedType == "Binary Data Files(*.bin *.dump)"))
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(ui->MF_File_keyBox->isChecked())
|
||||||
|
{
|
||||||
|
title = tr("Plz select the location to save key file:");
|
||||||
|
filename = QFileDialog::getSaveFileName(this, title, "./", tr("Binary Key Files(*.bin *.dump)"), &selectedType);
|
||||||
|
qDebug() << filename;
|
||||||
|
if(filename != "")
|
||||||
|
{
|
||||||
|
if(!mifare->data_saveKeyFile(filename, selectedType == "Binary Key Files(*.bin *.dump)"))
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug() << filename << selectedType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_File_clearButton_clicked()
|
||||||
|
{
|
||||||
|
if(ui->MF_File_keyBox->isChecked())
|
||||||
|
{
|
||||||
|
mifare->data_clearKey();
|
||||||
|
mifare->data_syncWithKeyWidget();
|
||||||
|
}
|
||||||
|
else if(ui->MF_File_dataBox->isChecked())
|
||||||
|
{
|
||||||
|
mifare->data_clearData();
|
||||||
|
mifare->data_syncWithDataWidget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_Attack_infoButton_clicked()
|
||||||
|
{
|
||||||
|
mifare->info();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_Attack_chkButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->chk();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_Attack_nestedButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->nested();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_Attack_hardnestedButton_clicked()
|
||||||
|
{
|
||||||
|
mifare->hardnested();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_RW_readAllButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->readAll();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_RW_readBlockButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->read();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_RW_writeBlockButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->write();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_RW_writeAllButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->writeAll();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_RW_dumpButton_clicked()
|
||||||
|
{
|
||||||
|
mifare->dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_RW_restoreButton_clicked()
|
||||||
|
{
|
||||||
|
mifare->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_readAllButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->readAllC();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_readBlockButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->readC();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_writeAllButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->writeAllC();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_writeBlockButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->writeC();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_wipeButton_clicked()
|
||||||
|
{
|
||||||
|
mifare->wipeC();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_aboutUIDButton_clicked()
|
||||||
|
{
|
||||||
|
QString msg;
|
||||||
|
msg += tr(" Normally, the Block 0 of a typical Mifare card, which contains the UID, is locked during the manufacture. Users cannot write anything to Block 0 or set a new UID to a normal Mifare card.") + "\n";
|
||||||
|
msg += tr(" Chinese Magic Cards(aka UID Cards) are some special cards whose Block 0 are writeable. And you can change UID by writing to it.") + "\n";
|
||||||
|
msg += "\n";
|
||||||
|
msg += tr("There are two versions of Chinese Magic Cards, the Gen1 and the Gen2.") + "\n";
|
||||||
|
msg += tr(" Gen1:") + "\n" + tr(" also called UID card in China. It responses to some backdoor commands so you can access any blocks without password. The Proxmark3 has a bunch of related commands(csetblk, cgetblk, ...) to deal with this type of card, and my GUI also support these commands.") + "\n";
|
||||||
|
msg += tr(" Gen2:") + "\n" + tr(" doesn't response to the backdoor commands, which means that a reader cannot detect whether it is a Chinese Magic Card or not by sending backdoor commands.") + "\n";
|
||||||
|
msg += "\n";
|
||||||
|
msg += tr("There are some types of Chinese Magic Card Gen2.") + "\n";
|
||||||
|
msg += tr(" CUID Card:") + "\n" + tr(" the Block 0 is writeable, you can write to this block repeatedly by normal wrbl command.") + "\n";
|
||||||
|
msg += tr(" (hf mf wrbl 0 A FFFFFFFFFFFF <the data you want to write>)") + "\n";
|
||||||
|
msg += tr(" FUID Card:") + "\n" + tr(" you can only write to Block 0 once. After that, it seems like a typical Mifare card(Block 0 cannot be written to).") + "\n";
|
||||||
|
msg += tr(" (some readers might try changing the Block 0, which could detect the CUID Card. In that case, you should use FUID card.)") + "\n";
|
||||||
|
msg += tr(" UFUID Card:") + "\n" + tr(" It behaves like a CUID card(or UID card? I'm not sure) before you send some special command to lock it. Once it is locked, you cannot change its Block 0(just like a typical Mifare card).") + "\n";
|
||||||
|
msg += "\n";
|
||||||
|
msg += tr(" Seemingly, these Chinese Magic Cards are more easily to be compromised by Nested Attack(it takes little time to get an unknown key).") + "\n";
|
||||||
|
QMessageBox::information(this, tr("About UID Card"), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_setParaButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->setParameterC();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_UID_lockButton_clicked()
|
||||||
|
{
|
||||||
|
mifare->lockC();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_Sniff_sniffButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->sniff();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_Sniff_listButton_clicked()
|
||||||
|
{
|
||||||
|
mifare->list();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::MF_widgetReset()
|
||||||
|
{
|
||||||
|
int secs = mifare->cardType.sectors;
|
||||||
|
int blks = mifare->cardType.blocks;
|
||||||
|
ui->MF_RW_blockBox->clear();
|
||||||
|
ui->MF_keyWidget->setRowCount(secs);
|
||||||
|
ui->MF_dataWidget->setRowCount(blks);
|
||||||
|
|
||||||
|
for(int i = 0; i < blks; i++)
|
||||||
|
{
|
||||||
|
setTableItem(ui->MF_dataWidget, i, 0, "");
|
||||||
|
setTableItem(ui->MF_dataWidget, i, 1, QString::number(i));
|
||||||
|
setTableItem(ui->MF_dataWidget, i, 2, "");
|
||||||
|
ui->MF_RW_blockBox->addItem(QString::number(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < secs; i++)
|
||||||
|
{
|
||||||
|
setTableItem(ui->MF_keyWidget, i, 0, QString::number(i));
|
||||||
|
setTableItem(ui->MF_keyWidget, i, 1, "");
|
||||||
|
setTableItem(ui->MF_keyWidget, i, 2, "");
|
||||||
|
setTableItem(ui->MF_dataWidget, mifare->cardType.blks[i], 0, QString::number(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ************************************************
|
||||||
|
|
||||||
|
|
||||||
|
// ******************** other ********************
|
||||||
|
|
||||||
|
void MainWindow::uiInit()
|
||||||
|
{
|
||||||
|
connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG);
|
||||||
|
|
||||||
|
connectStatusBar = new QLabel(this);
|
||||||
|
programStatusBar = new QLabel(this);
|
||||||
|
PM3VersionBar = new QLabel(this);
|
||||||
|
setStatusBar(connectStatusBar, tr("Not Connected"));
|
||||||
|
setStatusBar(programStatusBar, tr("Idle"));
|
||||||
|
setStatusBar(PM3VersionBar, "");
|
||||||
|
ui->statusbar->addPermanentWidget(PM3VersionBar, 1);
|
||||||
|
ui->statusbar->addPermanentWidget(connectStatusBar, 1);
|
||||||
|
ui->statusbar->addPermanentWidget(programStatusBar, 1);
|
||||||
|
|
||||||
|
ui->MF_dataWidget->setColumnCount(3);
|
||||||
|
ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
|
||||||
|
ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Blk")));
|
||||||
|
ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Data")));
|
||||||
|
ui->MF_dataWidget->verticalHeader()->setVisible(false);
|
||||||
|
ui->MF_dataWidget->setColumnWidth(0, 35);
|
||||||
|
ui->MF_dataWidget->setColumnWidth(1, 35);
|
||||||
|
ui->MF_dataWidget->setColumnWidth(2, 430);
|
||||||
|
|
||||||
|
ui->MF_keyWidget->setColumnCount(3);
|
||||||
|
ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
|
||||||
|
ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("KeyA")));
|
||||||
|
ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB")));
|
||||||
|
ui->MF_keyWidget->verticalHeader()->setVisible(false);
|
||||||
|
ui->MF_keyWidget->setColumnWidth(0, 35);
|
||||||
|
ui->MF_keyWidget->setColumnWidth(1, 115);
|
||||||
|
ui->MF_keyWidget->setColumnWidth(2, 115);
|
||||||
|
|
||||||
|
MF_widgetReset();
|
||||||
|
typeBtnGroup = new QButtonGroup(this);
|
||||||
|
typeBtnGroup->addButton(ui->MF_Type_miniButton, 0);
|
||||||
|
typeBtnGroup->addButton(ui->MF_Type_1kButton, 1);
|
||||||
|
typeBtnGroup->addButton(ui->MF_Type_2kButton, 2);
|
||||||
|
typeBtnGroup->addButton(ui->MF_Type_4kButton, 4);
|
||||||
|
connect(typeBtnGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MainWindow::MF_onTypeChanged);
|
||||||
|
|
||||||
|
ui->MF_keyWidget->installEventFilter(this);
|
||||||
|
ui->MF_dataWidget->installEventFilter(this);
|
||||||
|
|
||||||
|
on_Raw_CMDHistoryBox_stateChanged(Qt::Unchecked);
|
||||||
|
on_PM3_refreshPortButton_clicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::signalInit()
|
||||||
|
{
|
||||||
|
connect(pm3, &PM3Process::newOutput, util, &Util::processOutput);
|
||||||
|
connect(util, &Util::refreshOutput, this, &MainWindow::refreshOutput);
|
||||||
|
|
||||||
|
connect(this, &MainWindow::connectPM3, pm3, &PM3Process::connectPM3);
|
||||||
|
connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged);
|
||||||
|
connect(this, &MainWindow::killPM3, pm3, &PM3Process::kill);
|
||||||
|
|
||||||
|
connect(util, &Util::write, pm3, &PM3Process::write);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setStatusBar(QLabel* target, const QString & text)
|
||||||
|
{
|
||||||
|
if(target == PM3VersionBar)
|
||||||
|
target->setText(tr("HW Version:") + text);
|
||||||
|
else if(target == connectStatusBar)
|
||||||
|
target->setText(tr("PM3:") + text);
|
||||||
|
else if(target == programStatusBar)
|
||||||
|
target->setText(tr("State:") + text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setTableItem(QTableWidget* widget, int row, int column, const QString& text)
|
||||||
|
{
|
||||||
|
if(widget->item(row, column) == nullptr)
|
||||||
|
widget->setItem(row, column, new QTableWidgetItem());
|
||||||
|
widget->item(row, column)->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::eventFilter(QObject *watched, QEvent *event) // drag support
|
||||||
|
{
|
||||||
|
if(event->type() == QEvent::DragEnter)
|
||||||
|
{
|
||||||
|
QDragEnterEvent* dragEvent = static_cast<QDragEnterEvent*>(event);
|
||||||
|
dragEvent->acceptProposedAction();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(event->type() == QEvent::Drop)
|
||||||
|
{
|
||||||
|
QDropEvent* dropEvent = static_cast<QDropEvent*>(event);
|
||||||
|
if(watched == ui->MF_keyWidget)
|
||||||
|
{
|
||||||
|
const QMimeData* mime = dropEvent->mimeData();
|
||||||
|
if(mime->hasUrls())
|
||||||
|
{
|
||||||
|
QList<QUrl> urls = mime->urls();
|
||||||
|
if(urls.length() == 1)
|
||||||
|
{
|
||||||
|
mifare->data_loadKeyFile(urls[0].toLocalFile());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(watched == ui->MF_dataWidget)
|
||||||
|
{
|
||||||
|
const QMimeData* mime = dropEvent->mimeData();
|
||||||
|
if(mime->hasUrls())
|
||||||
|
{
|
||||||
|
QList<QUrl> urls = mime->urls();
|
||||||
|
if(urls.length() == 1)
|
||||||
|
{
|
||||||
|
mifare->data_loadDataFile(urls[0].toLocalFile());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QMainWindow::eventFilter(watched, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setState(bool st)
|
||||||
|
{
|
||||||
|
if(!st && pm3state)
|
||||||
|
{
|
||||||
|
setStatusBar(programStatusBar, tr("Running"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setStatusBar(programStatusBar, tr("Idle"));
|
||||||
|
}
|
||||||
|
ui->MF_attackGroupBox->setEnabled(st);
|
||||||
|
ui->MF_normalGroupBox->setEnabled(st);
|
||||||
|
ui->MF_UIDGroupBox->setEnabled(st);
|
||||||
|
ui->MF_simGroupBox->setEnabled(st);
|
||||||
|
ui->MF_sniffGroupBox->setEnabled(st);
|
||||||
|
ui->Raw_CMDEdit->setEnabled(st);
|
||||||
|
ui->Raw_sendCMDButton->setEnabled(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***********************************************
|
149
ui/mainwindow.h
Normal file
149
ui/mainwindow.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QListWidgetItem>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFontDialog>
|
||||||
|
#include <QtSerialPort/QSerialPortInfo>
|
||||||
|
#include <QtSerialPort/QSerialPort>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
|
#include "common/pm3process.h"
|
||||||
|
#include "module/mifare.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
void initUI();
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event);
|
||||||
|
public slots:
|
||||||
|
void refreshOutput(const QString &output);
|
||||||
|
void refreshCMD(const QString &cmd);
|
||||||
|
void setStatusBar(QLabel* target, const QString & text);
|
||||||
|
void onPM3StateChanged(bool st, QString info);
|
||||||
|
void MF_onTypeChanged(int id, bool st);
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void on_PM3_connectButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_sendCMDButton_clicked();
|
||||||
|
|
||||||
|
void on_PM3_disconnectButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_clearOutputButton_clicked();
|
||||||
|
|
||||||
|
void sendMSG();
|
||||||
|
void on_PM3_refreshPortButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_CMDHistoryBox_stateChanged(int arg1);
|
||||||
|
|
||||||
|
void on_Raw_clearHistoryButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_CMDHistoryWidget_itemDoubleClicked(QListWidgetItem *item);
|
||||||
|
|
||||||
|
void on_MF_Attack_chkButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Attack_nestedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Attack_hardnestedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sniff_sniffButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sniff_listButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_readAllButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_readBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_writeBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Attack_infoButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_writeAllButton_clicked();
|
||||||
|
|
||||||
|
|
||||||
|
void on_MF_RW_dumpButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_restoreButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_readAllButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_readBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_writeAllButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_writeBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_File_loadButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_File_saveButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_data2KeyBotton_clicked();
|
||||||
|
|
||||||
|
void on_MF_key2DataBotton_clicked();
|
||||||
|
|
||||||
|
void on_MF_dataWidget_itemChanged(QTableWidgetItem *item);
|
||||||
|
|
||||||
|
void on_MF_File_clearButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_keyWidget_itemChanged(QTableWidgetItem *item);
|
||||||
|
|
||||||
|
void on_MF_fontButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_wipeButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_aboutUIDButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_setParaButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_lockButton_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow* ui;
|
||||||
|
QButtonGroup* typeBtnGroup;
|
||||||
|
QLabel* connectStatusBar;
|
||||||
|
QLabel* programStatusBar;
|
||||||
|
QLabel* PM3VersionBar;
|
||||||
|
QAction* myInfo;
|
||||||
|
|
||||||
|
void uiInit();
|
||||||
|
|
||||||
|
PM3Process* pm3;
|
||||||
|
bool pm3state;
|
||||||
|
QThread* pm3Thread;
|
||||||
|
|
||||||
|
Mifare* mifare;
|
||||||
|
Util* util;
|
||||||
|
|
||||||
|
|
||||||
|
void signalInit();
|
||||||
|
void MF_widgetReset();
|
||||||
|
void setTableItem(QTableWidget *widget, int row, int column, const QString &text);
|
||||||
|
void setState(bool st);
|
||||||
|
signals:
|
||||||
|
void connectPM3(const QString path, const QString port);
|
||||||
|
void killPM3();
|
||||||
|
void setSerialListener(const QString &name, bool state);
|
||||||
|
};
|
||||||
|
#endif // MAINWINDOW_H
|
1108
ui/mainwindow.ui
Normal file
1108
ui/mainwindow.ui
Normal file
File diff suppressed because it is too large
Load Diff
34
ui/mf_attack_hardnesteddialog.cpp
Normal file
34
ui/mf_attack_hardnesteddialog.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "mf_attack_hardnesteddialog.h"
|
||||||
|
#include "ui_mf_attack_hardnesteddialog.h"
|
||||||
|
|
||||||
|
MF_Attack_hardnestedDialog::MF_Attack_hardnestedDialog(int blocks, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::MF_Attack_hardnestedDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
for(int i = 0; i < blocks; i++)
|
||||||
|
{
|
||||||
|
ui->knownKeySectorBox->addItem(QString::number(i));
|
||||||
|
ui->targetKeySectorBox->addItem(QString::number(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MF_Attack_hardnestedDialog::~MF_Attack_hardnestedDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_Attack_hardnestedDialog::on_buttonBox_accepted()
|
||||||
|
{
|
||||||
|
emit sendCMD("hf mf hardnested "
|
||||||
|
+ ui->knownKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyTypeBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyBox->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeyTypeBox->currentText());
|
||||||
|
}
|
27
ui/mf_attack_hardnesteddialog.h
Normal file
27
ui/mf_attack_hardnesteddialog.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef MF_ATTACK_HARDNESTEDDIALOG_H
|
||||||
|
#define MF_ATTACK_HARDNESTEDDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MF_Attack_hardnestedDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MF_Attack_hardnestedDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MF_Attack_hardnestedDialog(int blocks, QWidget *parent = nullptr);
|
||||||
|
~MF_Attack_hardnestedDialog();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MF_Attack_hardnestedDialog *ui;
|
||||||
|
signals:
|
||||||
|
void sendCMD(QString cmd);
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_accepted();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MF_ATTACK_HARDNESTEDDIALOG_H
|
228
ui/mf_attack_hardnesteddialog.ui
Normal file
228
ui/mf_attack_hardnesteddialog.ui
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MF_Attack_hardnestedDialog</class>
|
||||||
|
<widget class="QDialog" name="MF_Attack_hardnestedDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>287</width>
|
||||||
|
<height>173</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Hardnested Attack</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Known Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="knownKeySectorBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="knownKeyTypeBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>A</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>B</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="knownKeyBox">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Courier</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">FFFFFFFFFFFF</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Target Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="targetKeySectorBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="targetKeyTypeBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>A</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>B</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>MF_Attack_hardnestedDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>MF_Attack_hardnestedDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
27
ui/mf_uid_parameterdialog.cpp
Normal file
27
ui/mf_uid_parameterdialog.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "mf_uid_parameterdialog.h"
|
||||||
|
#include "ui_mf_uid_parameterdialog.h"
|
||||||
|
|
||||||
|
MF_UID_parameterDialog::MF_UID_parameterDialog(const QString& uid, const QString& atqa, const QString& sak, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::MF_UID_parameterDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->UIDLineEdit->setText(uid);
|
||||||
|
ui->ATQALineEdit->setText(atqa);
|
||||||
|
ui->SAKLineEdit->setText(sak);
|
||||||
|
}
|
||||||
|
|
||||||
|
MF_UID_parameterDialog::~MF_UID_parameterDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_UID_parameterDialog::on_buttonBox_accepted()
|
||||||
|
{
|
||||||
|
emit sendCMD("hf mf csetuid "
|
||||||
|
+ ui->UIDLineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->ATQALineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->SAKLineEdit->text());
|
||||||
|
}
|
26
ui/mf_uid_parameterdialog.h
Normal file
26
ui/mf_uid_parameterdialog.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef MF_UID_PARAMETERDIALOG_H
|
||||||
|
#define MF_UID_PARAMETERDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MF_UID_parameterDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MF_UID_parameterDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MF_UID_parameterDialog(const QString& uid, const QString& atqa, const QString& sak, QWidget *parent = nullptr);
|
||||||
|
~MF_UID_parameterDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MF_UID_parameterDialog *ui;
|
||||||
|
signals:
|
||||||
|
void sendCMD(QString cmd);
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_accepted();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MF_UID_PARAMETERDIALOG_H
|
111
ui/mf_uid_parameterdialog.ui
Normal file
111
ui/mf_uid_parameterdialog.ui
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MF_UID_parameterDialog</class>
|
||||||
|
<widget class="QDialog" name="MF_UID_parameterDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>205</width>
|
||||||
|
<height>186</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Set Parameter</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="uIDLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>UID:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="UIDLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="ATQALabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>ATQA:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="ATQALineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="SAKLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>SAK:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="SAKLineEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>MF_UID_parameterDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>MF_UID_parameterDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
Loading…
x
Reference in New Issue
Block a user