45 Commits

Author SHA1 Message Date
wh201906 bec81e6c7d V0.1 2020-04-29 20:49:23 +08:00
wh201906 0f2cca9a98 Update translation 2020-04-29 19:05:05 +08:00
wh201906 526bd89873 Add running state 2020-04-29 17:50:52 +08:00
wh201906 a65bcffffd Refactor file reading function 2020-04-29 17:12:35 +08:00
wh201906 2b8e31e452 Support dragging files 2020-04-29 16:30:27 +08:00
wh201906 e34c36e572 Complete Chinese Magic Card module 2020-04-29 14:47:40 +08:00
wh201906 383eaff2a5 Support editing data and key manually 2020-04-28 19:54:05 +08:00
wh201906 c74cdee924 Support save data file and key file 2020-04-27 23:57:21 +08:00
wh201906 6080ac7d7c Add key2data and data2key function 2020-04-26 21:50:55 +08:00
wh201906 c97c550439 Support load data file and key file 2020-04-26 21:15:08 +08:00
wh201906 6765a84a80 little tiny fix 2020-04-25 18:30:45 +08:00
wh201906 767a651735 Add support for multilanguage 2020-04-25 18:15:00 +08:00
wh201906 d793c41aa5 Support backdoor command for Chinese Magic Card(GEN 1a) 2020-04-25 00:57:28 +08:00
wh201906 41015fd1fe Support Mifare MINI, 1k, 2k and 4k card 2020-04-24 22:11:35 +08:00
wh201906 05d44604a4 Use regex to process output 2020-04-24 16:25:52 +08:00
wh201906 23eb3f8ab3 Redesign UI 2020-04-24 00:36:33 +08:00
wh201906 ac7f1b33dd Increase read speed(replace rdbl with rdsc) 2020-04-23 23:54:51 +08:00
wh201906 b6be875261 Redesign UI 2020-04-23 20:46:27 +08:00
wh201906 b2fa97ff18 Store keys and data into class Mifare 2020-04-23 17:50:20 +08:00
wh201906 0be1eb5041 Complete the Mifare_Attack and Mifare_Read/Write functions 2020-04-22 23:35:24 +08:00
wh201906 abfc940dc8 Refactor(nothing changed actually) 2020-04-22 23:13:00 +08:00
wh201906 a325e3b670 Replace the default font with monospaced font(Courier) 2020-04-22 21:34:28 +08:00
wh201906 a6302f8fa8 Optimize with multithread 2020-04-22 21:14:33 +08:00
wh201906 ed1e9cb1d6 Refactor project structure 2020-04-22 16:42:58 +08:00
wh201906 a6a699d33c Make execCmd() adapted to QThread 2020-04-22 16:00:56 +08:00
wh201906 5c5fb84811 Delete command help view(It's hard for me to resolve the -help output now) 2020-04-21 19:28:38 +08:00
wh201906 6b8e98b735 Refactor the basic connect function(using QThread) 2020-04-21 19:12:44 +08:00
wh201906 80a8db540f Optimize the read logic and complete PM3 connection state 2020-04-18 02:01:42 +08:00
wh201906 b540741b1a Optimize ReadAll function(fill the KeyA and KeyB automatically) 2020-04-17 02:24:45 +08:00
wh201906 fd009745f9 Update README.md 2020-04-16 12:58:18 +08:00
wh201906 fc91bfee2c Add MF_ReadBlock/WriteBlock function 2020-04-16 01:03:53 +08:00
wh201906 c25e2f9e4a Add MF_ReadAll function 2020-04-16 00:39:10 +08:00
wh201906 1d8d931752 Add hardnested dialog 2020-04-15 00:38:43 +08:00
wh201906 b3fd3ba378 Match widgets to their slots, add status bar 2020-04-13 15:54:37 +08:00
wh201906 01e6a134cd Merge branch 'dev' of github.com:wh201906/Proxmark3GUI into dev
just for sync
2020-04-12 23:41:32 +08:00
wh201906 15a1950a23 Refactor ui(complete the mifare tab and rename some widgets) 2020-04-12 23:31:52 +08:00
wh201906 037731de64 Merge pull request #1 from wh201906/master
just for sync
2020-04-12 00:08:31 +08:00
wh201906 4aa5654ffd Try to process the origin output(in hf mf nested) 2020-04-11 23:59:16 +08:00
wh201906 5d793eb764 Try to process the origin output(in hf mf chk) 2020-04-11 23:53:06 +08:00
wh201906 d9e993be9a Create LICENSE 2020-04-09 09:18:34 +08:00
wh201906 d2689c333c refactor 2020-04-09 09:10:47 +08:00
wh201906 e09fdf1b9b add command history 2020-04-08 18:18:53 +08:00
wh201906 643c298662 dev commit 2020-04-07 23:57:56 +08:00
wh201906 d651d2788d dev commit 2020-04-07 21:24:49 +08:00
wh201906 db356a2e55 A useless, uncompleted version 2020-04-07 18:28:41 +08:00
32 changed files with 5062 additions and 392 deletions
+73 -73
View File
@@ -1,73 +1,73 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 wh201906
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+20 -6
View File
@@ -17,22 +17,36 @@ DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp \
pm3process.cpp
common/pm3process.cpp \
common/util.cpp \
module/mifare.cpp \
ui/mf_uid_parameterdialog.cpp \
ui/mainwindow.cpp \
ui/mf_attack_hardnesteddialog.cpp \
HEADERS += \
mainwindow.h \
pm3process.h
common/pm3process.h \
common/util.h \
module/mifare.h \
ui/mf_uid_parameterdialog.h \
ui/mainwindow.h \
ui/mf_attack_hardnesteddialog.h \
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.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
VERSION = 0.0.1
VERSION = 0.1
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
QMAKE_TARGET_COMPANY = "wh201906"
+29 -3
View File
@@ -1,9 +1,35 @@
# 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.
+35
View 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
+ 一个带串口选择框的实验版本
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 KiB

+102
View 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
View 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
View 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
View 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
View 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>&gt;&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/mainwindow.ui" line="231"/>
<source>&lt;&lt;</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&apos;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 &lt;the data you want to write&gt;)</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&apos;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
View 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>&gt;&gt;</source>
<translation></translation>
</message>
<message>
<location filename="../ui/mainwindow.ui" line="231"/>
<source>&lt;&lt;</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 CardBlock0可写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&apos;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 &lt;the data you want to write&gt;)</source>
<translation> (hf mf wrbl 0 A FFFFFFFFFFFF &lt;&gt;)</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&apos;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卡一样可以反复读写Block0FUID卡一样了</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>
+57 -11
View File
@@ -1,11 +1,57 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "ui/mainwindow.h"
#include <QApplication>
#include <QSettings>
#include <QTranslator>
#include <QMessageBox>
#include <QInputDialog>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
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();
return a.exec();
}
-67
View File
@@ -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
View File
@@ -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
View File
@@ -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
View 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
View 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
-29
View File
@@ -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
View File
@@ -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
View 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
View 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
View File
File diff suppressed because it is too large Load Diff
+34
View 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
View 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
View 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
View 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
View 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
View 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>