Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa6b93984c | |||
| 7f96c061dc | |||
| b8c4e8e339 | |||
| 4f10e3d75c | |||
| 63f3424871 | |||
| 24a6e1869b | |||
| 6baa09221e | |||
| 6e5f654cc5 | |||
| 83445c7eef | |||
| 5330ed8d14 | |||
| a56a503b23 | |||
| 77d8049738 | |||
| bf9b3fb076 | |||
| 6d3dd5056c | |||
| e687cc39fd | |||
| 3c3944d150 | |||
| 091b4f63d1 | |||
| 0c4220c9a5 | |||
| 986e9aacfe | |||
| ce262db52c | |||
| 73533608e6 | |||
| 2f38d3c8c5 | |||
| f2d00ee088 | |||
| 862f0775f8 | |||
| a7985c5c89 | |||
| a3e6aa787b | |||
| 1c273a6527 | |||
| 3f899845b7 | |||
| 475580c342 | |||
| 3a577bdd32 | |||
| f8d2bbb206 | |||
| d6beafe175 | |||
| f881a05fa3 | |||
| ad10a6e789 | |||
| bf8136a7fe | |||
| 6af85bffc0 | |||
| 3751349004 | |||
| 44c61a8202 | |||
| fbe8a5e51d | |||
| 41bbcd2c4a | |||
| 4dba7882e5 | |||
| 25d7886f2a | |||
| 7e4dedeff1 | |||
| 7dfabb60e9 | |||
| 46b3912e82 | |||
| fe8f8b2d51 | |||
| d15b8e21fc | |||
| eb5fa7ec9a | |||
| ef6ebea568 | |||
| 6f860111df | |||
| a935ff9703 | |||
| 02b0c312a4 | |||
| 946d0acb01 | |||
| a60b28ee66 | |||
| 43752bd5e4 | |||
| a77985824c | |||
| cd122b8959 | |||
| 87dddf4d3d | |||
| b2baaede5d | |||
| 7ea9c363fd | |||
| 241b0cdc29 | |||
| 3181848e75 | |||
| 5cccb7b8bb | |||
| 461c48fee9 | |||
| 2790afc193 | |||
| 5816d1b1b6 | |||
| fe8b9d6161 | |||
| afe2474fe3 | |||
| 0995e529ad | |||
| b44488fbed | |||
| 5f1df6782a |
@@ -14,7 +14,6 @@
|
||||
*.so.*
|
||||
*_pch.h.cpp
|
||||
*_resource.rc
|
||||
*.qm
|
||||
.#*
|
||||
*.*#
|
||||
core
|
||||
|
||||
@@ -16,23 +16,31 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
common/myeventfilter.cpp \
|
||||
main.cpp \
|
||||
common/pm3process.cpp \
|
||||
common/util.cpp \
|
||||
module/mifare.cpp \
|
||||
ui/mf_trailerdecoderdialog.cpp \
|
||||
ui/mf_sim_simdialog.cpp \
|
||||
ui/mf_uid_parameterdialog.cpp \
|
||||
ui/mainwindow.cpp \
|
||||
ui/mf_attack_hardnesteddialog.cpp \
|
||||
|
||||
HEADERS += \
|
||||
common/myeventfilter.h \
|
||||
common/pm3process.h \
|
||||
common/util.h \
|
||||
module/mifare.h \
|
||||
ui/mf_trailerdecoderdialog.h \
|
||||
ui/mf_sim_simdialog.h \
|
||||
ui/mf_uid_parameterdialog.h \
|
||||
ui/mainwindow.h \
|
||||
ui/mf_attack_hardnesteddialog.h \
|
||||
|
||||
FORMS += \
|
||||
ui/mf_trailerdecoderdialog.ui \
|
||||
ui/mf_sim_simdialog.ui \
|
||||
ui/mf_uid_parameterdialog.ui \
|
||||
ui/mainwindow.ui \
|
||||
ui/mf_attack_hardnesteddialog.ui
|
||||
@@ -46,7 +54,7 @@ qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
VERSION = 0.1
|
||||
VERSION = 0.1.4
|
||||
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
||||
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
||||
QMAKE_TARGET_COMPANY = "wh201906"
|
||||
|
||||
@@ -1,33 +1,96 @@
|
||||
# Proxmark3GUI
|
||||
A GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client
|
||||

|
||||
|
||||
[中文](README/README.zh_CN.md)
|
||||
A cross-platform GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client
|
||||
|
||||
[中文](README/doc/README_zh_CN.md)
|
||||
|
||||
***
|
||||
|
||||
## Features
|
||||
|
||||
+ Support raw commands of Proxmark3 client
|
||||
+ Easy to find available Serial Port
|
||||
+ Support raw commands of Proxmark3 client(Official/Iceman)
|
||||
+ Have a friendly UI to test Mifare cards
|
||||
+ Easy to edit Mifare data files
|
||||
+ Support binary(.bin .dump) files and text(.eml) files
|
||||
+ Support different card size(MINI, 1K, 2K, 4K)
|
||||
+ Easy to edit Mifare block data
|
||||
+ Easy to read all/selected blocks with well-designed read logic
|
||||
+ Easy to write all/selected blocks
|
||||
+ Support binary(.bin .dump) files and text(.eml) files
|
||||
+ Analyze Access Bits
|
||||
+ Support Chinese Magic Card
|
||||
+ Customize UI
|
||||
+ ...
|
||||
|
||||
***
|
||||
|
||||
## Previews
|
||||

|
||||
## Preview
|
||||

|
||||
|
||||

|
||||
[more previews](README/doc/previews.md)
|
||||
|
||||

|
||||
***
|
||||
|
||||

|
||||
## About Iceman fork/repo
|
||||
|
||||
The [Iceman fork/repo](https://github.com/RfidResearchGroup/proxmark3) has more powerful functions like offline sniff. These guys even developed a new hardware called Proxmark3 RDV4 with smart card support. But the official repo and the Iceman repo is not fully compatible.
|
||||
This GUI is compatible with Iceman/RRG repo(tested on v4.9237)
|
||||
|
||||
***
|
||||
|
||||
## About Compiled Windows clients
|
||||
|
||||
A cool guy [Gator96100](https://github.com/Gator96100) creates [ProxSpace](https://github.com/Gator96100/ProxSpace) and makes it possible to compile both the firmware and client on Windows.
|
||||
Also, he makes the [pre-compiled Windows client](https://www.proxmarkbuilds.org/) so you can download it and run your PM3 client on Windows instantly.
|
||||
I included his compiled client in my releases so you can use the GUI on the fly, and you can also use the GUI with your prefered client.
|
||||
Great thanks to him.
|
||||
|
||||
***
|
||||
|
||||
## Build on Linux
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/wh201906/Proxmark3GUI.git
|
||||
cd Proxmark3GUI
|
||||
mkdir build
|
||||
cd build
|
||||
qmake ../
|
||||
make
|
||||
make clean
|
||||
cp -r ../lang ./
|
||||
./Proxmark3GUI
|
||||
|
||||
***
|
||||
|
||||
## Update Log:
|
||||
|
||||
### V0.1.4
|
||||
+ Optimize performance
|
||||
+ Optimize UI
|
||||
+ Search available ports automatically
|
||||
+ Add High-DPI support
|
||||
+ Support configuring environment variables by script
|
||||
(Useful when the client requires specific environment variables)
|
||||
+ All functions are compatible with Iceman/RRG repo(tested on v4.9237)
|
||||
+ Support specifying client working directory
|
||||
+ Fix some bugs
|
||||
|
||||
### V0.1.3
|
||||
+ Fix Trailer Decoder
|
||||
+ Add feedback when writing selected blocks
|
||||
|
||||
### V0.1.2
|
||||
+ Optimize read logic
|
||||
+ Make UI Customizable
|
||||
+ Save client path automatically
|
||||
+ Add Trailer Decoder(Deprecated, plz use V0.1.3 or higher version)
|
||||
+ Support read/write selected blocks
|
||||
+ Support a few Iceman functions
|
||||
+ Fix some bugs
|
||||
|
||||
### V0.1.1
|
||||
+ Complete Mifare module(support simulate and sniff)
|
||||
|
||||
### V0.1
|
||||
+ Able to deal with Mifare card and related files
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# Proxmark3GUI
|
||||
一个自制的[Proxmark3](https://github.com/Proxmark/proxmark3) GUI
|
||||
|
||||
[English](../README.md)
|
||||
|
||||
***
|
||||
|
||||
## 特色功能
|
||||
|
||||
+ 支持直接输入PM3命令
|
||||
+ 有针对于Mifare卡(IC卡)的图形界面
|
||||
+ 支持编辑Mifare扇区数据文件
|
||||
+ 可以打开二进制/文本格式的扇区数据文件
|
||||
+ ...
|
||||
|
||||
***
|
||||
|
||||
## 预览图
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
***
|
||||
|
||||
## 更新日志:
|
||||
|
||||
### V0.1
|
||||
+ 支持处理Mifare卡片及相关数据文件
|
||||
|
||||
### V0.0.1
|
||||
+ 一个带串口选择框的实验版本
|
||||
@@ -0,0 +1,97 @@
|
||||
# Proxmark3GUI
|
||||

|
||||
|
||||
一个自制的[Proxmark3](https://github.com/Proxmark/proxmark3) GUI,可在Windows/Linux系统下运行
|
||||
|
||||
[English](../../README.md)
|
||||
|
||||
***
|
||||
|
||||
## 功能
|
||||
|
||||
+ 快速查找可用端口并连接
|
||||
+ 支持直接输入PM3命令(官方版/冰人版)
|
||||
+ 有针对于Mifare卡(IC卡)的图形界面
|
||||
+ 支持不同大小的卡片(MINI, 1K, 2K, 4K)
|
||||
+ 支持编辑Mifare扇区数据
|
||||
+ 支持读取全卡/选中扇区,读卡逻辑更加智能
|
||||
+ 支持写入全卡/选中扇区
|
||||
+ 可以打开二进制/文本格式的扇区数据文件
|
||||
+ 分析访问控制位(Access Bits)
|
||||
+ 支持UID卡操作(UID快速读写,UFUID锁卡)
|
||||
+ 自定义UI界面
|
||||
+ ...
|
||||
|
||||
***
|
||||
|
||||
## 预览图
|
||||

|
||||
|
||||
[更多预览](../doc/previews.md)
|
||||
|
||||
***
|
||||
|
||||
## 关于冰人版
|
||||
[冰人版](https://github.com/RfidResearchGroup/proxmark3)(Iceman/RRG)的客户端和固件更新更为激进,相比官方版具有更多的功能
|
||||
此GUI所有功能均兼容冰人版(在v4.9237上测试通过)
|
||||
|
||||
***
|
||||
|
||||
## 关于预编译Windows客户端
|
||||
|
||||
一位国外大佬 [Gator96100](https://github.com/Gator96100) 做了个 [ProxSpace](https://github.com/Gator96100/ProxSpace) 以便在Windows平台上编译PM3固件和客户端,他还把自己编译好的客户端放到了[网站](https://www.proxmarkbuilds.org/)上
|
||||
release页面中有含客户端的GUI。这个GUI也可以搭配你自己的客户端使用
|
||||
(本来打算在CSDN下载里面放几个最新版客户端的,结果不能把下载币改为0)
|
||||
感谢大佬
|
||||
|
||||
***
|
||||
|
||||
## 在Linux系统下编译
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/wh201906/Proxmark3GUI.git
|
||||
cd Proxmark3GUI
|
||||
mkdir build
|
||||
cd build
|
||||
qmake ../
|
||||
make
|
||||
make clean
|
||||
cp -r ../lang ./
|
||||
./Proxmark3GUI
|
||||
|
||||
***
|
||||
|
||||
## 更新日志:
|
||||
|
||||
### V0.1.4
|
||||
+ 优化性能
|
||||
+ 优化用户界面
|
||||
+ 自动搜索可用端口
|
||||
+ 支持高分屏
|
||||
+ 可通过外部脚本配置环境变量
|
||||
(在客户端需要配置环境变量时很有用)
|
||||
+ 全功能兼容冰人版(在v4.9237上测试通过)
|
||||
+ 支持指定客户端工作路径
|
||||
+ 修复部分bug
|
||||
|
||||
### V0.1.3
|
||||
+ 修复访问控制位解码器
|
||||
+ 写多个块时显示写入结果
|
||||
|
||||
### V0.1.2
|
||||
+ 优化读卡逻辑
|
||||
+ UI自定义
|
||||
+ 自动保存客户端路径
|
||||
+ 添加访问控制位解码器(也可用于自己构造访问控制位)(有bug,请使用V0.1.3或更高版本)
|
||||
+ 支持仅读写选中块
|
||||
+ 支持部分冰人功能
|
||||
+ 修复部分bug
|
||||
|
||||
### V0.1.1
|
||||
+ 完成整个Mifare模块(支持模拟卡和嗅探功能)
|
||||
|
||||
### V0.1
|
||||
+ 支持处理Mifare卡片及相关数据文件
|
||||
|
||||
### V0.0.1
|
||||
+ 一个带串口选择框的实验版本
|
||||
@@ -0,0 +1,16 @@
|
||||
## Previews
|
||||
|
||||
Raw Command:
|
||||

|
||||
|
||||
Mifare Nested Attack:
|
||||

|
||||
|
||||
Mifare Load File:
|
||||

|
||||
|
||||
Mifare Edit File:
|
||||

|
||||
|
||||
Mifare Trailer Decoder:
|
||||

|
||||
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 797 KiB |
|
After Width: | Height: | Size: 438 KiB |
|
After Width: | Height: | Size: 468 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 345 KiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 650 KiB |
|
Before Width: | Height: | Size: 637 KiB |
|
Before Width: | Height: | Size: 857 KiB |
@@ -0,0 +1,13 @@
|
||||
#include "myeventfilter.h"
|
||||
|
||||
MyEventFilter::MyEventFilter(QEvent::Type filter)
|
||||
{
|
||||
targetEventType = filter;
|
||||
}
|
||||
|
||||
bool MyEventFilter::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if(event->type() == targetEventType)
|
||||
emit eventHappened(obj, *event);
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef MYEVENTFILTER_H
|
||||
#define MYEVENTFILTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QKeyEvent>
|
||||
|
||||
class MyEventFilter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MyEventFilter(QEvent::Type filter);
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
signals:
|
||||
void eventHappened(QObject* obj_addr, QEvent& event);
|
||||
private:
|
||||
QEvent::Type targetEventType;
|
||||
};
|
||||
|
||||
#endif // MYEVENTFILTER_H
|
||||
@@ -14,24 +14,51 @@ PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent)
|
||||
connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead);
|
||||
}
|
||||
|
||||
void PM3Process::connectPM3(const QString path, const QString port)
|
||||
void PM3Process::connectPM3(const QString& path, const QString& port, const QStringList args)
|
||||
{
|
||||
QString result;
|
||||
Util::ClientType clientType;
|
||||
setRequiringOutput(true);
|
||||
|
||||
// stash for reconnect
|
||||
currPath = path;
|
||||
currPort = port;
|
||||
currArgs = args;
|
||||
|
||||
// using "-f" option to make the client output flushed after every print.
|
||||
start(path, QStringList() << port << "-f", QProcess::Unbuffered | QProcess::ReadWrite);
|
||||
start(path, args, QProcess::Unbuffered | QProcess::ReadWrite);
|
||||
if(waitForStarted(10000))
|
||||
{
|
||||
while(waitForReadyRead(1000))
|
||||
;
|
||||
waitForReadyRead(10000);
|
||||
setRequiringOutput(false);
|
||||
QString result = *requiredOutput;
|
||||
result = *requiredOutput;
|
||||
if(result.indexOf("[=]") != -1)
|
||||
{
|
||||
clientType = Util::CLIENTTYPE_ICEMAN;
|
||||
setRequiringOutput(true);
|
||||
write("hw version\r\n");
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
waitForReadyRead(200);
|
||||
result += *requiredOutput;
|
||||
}
|
||||
setRequiringOutput(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
clientType = Util::CLIENTTYPE_OFFICIAL;
|
||||
}
|
||||
if(result.indexOf("os: ") != -1) // make sure the PM3 is connected
|
||||
{
|
||||
emit changeClientType(clientType);
|
||||
result = result.mid(result.indexOf("os: "));
|
||||
result = result.left(result.indexOf("\r\n"));
|
||||
result = result.mid(3, result.lastIndexOf(" ") - 3);
|
||||
emit PM3StatedChanged(true, result);
|
||||
|
||||
// if the arguments don't contain <port>, then disable the port listener
|
||||
// useful when using offline sniff
|
||||
if(args.indexOf(port) != -1)
|
||||
setSerialListener(port, true);
|
||||
}
|
||||
else
|
||||
@@ -39,6 +66,11 @@ void PM3Process::connectPM3(const QString path, const QString port)
|
||||
}
|
||||
}
|
||||
|
||||
void PM3Process::reconnectPM3()
|
||||
{
|
||||
connectPM3(currPath, currPort, currArgs);
|
||||
}
|
||||
|
||||
void PM3Process::setRequiringOutput(bool st)
|
||||
{
|
||||
isRequiringOutput = st;
|
||||
@@ -82,7 +114,6 @@ void PM3Process::testThread()
|
||||
qDebug() << "PM3:" << QThread::currentThread();
|
||||
}
|
||||
|
||||
|
||||
qint64 PM3Process::write(QString data)
|
||||
{
|
||||
return QProcess::write(data.toLatin1());
|
||||
@@ -100,3 +131,16 @@ void PM3Process::onReadyRead()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void PM3Process::setProcEnv(const QStringList* env)
|
||||
{
|
||||
// qDebug() << "passed Env List" << *env;
|
||||
this->setEnvironment(*env);
|
||||
// qDebug() << "final Env List" << processEnvironment().toStringList();
|
||||
}
|
||||
|
||||
void PM3Process::setWorkingDir(const QString& dir)
|
||||
{
|
||||
// the working directory cannot be the default, or the client will failed to load the dll
|
||||
this->setWorkingDirectory(dir);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include <QTimer>
|
||||
#include <QtSerialPort/QSerialPortInfo>
|
||||
#include <QtSerialPort/QSerialPort>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QDir>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
class PM3Process : public QProcess
|
||||
{
|
||||
@@ -19,9 +23,12 @@ public:
|
||||
void testThread();
|
||||
|
||||
public slots:
|
||||
void connectPM3(const QString path, const QString port);
|
||||
void setSerialListener(const QString &name, bool state);
|
||||
void connectPM3(const QString& path, const QString& port, const QStringList args);
|
||||
void setSerialListener(const QString& name, bool state);
|
||||
qint64 write(QString data);
|
||||
void reconnectPM3();
|
||||
void setProcEnv(const QStringList* env);
|
||||
void setWorkingDir(const QString& dir);
|
||||
private slots:
|
||||
void onTimeout();
|
||||
void onReadyRead();
|
||||
@@ -31,9 +38,14 @@ private:
|
||||
void setRequiringOutput(bool st);// It only works in this class now
|
||||
QTimer* serialListener;
|
||||
QSerialPortInfo* portInfo;
|
||||
QString currPath;
|
||||
QString currPort;
|
||||
QStringList currArgs;
|
||||
|
||||
signals:
|
||||
void PM3StatedChanged(bool st, QString info = "");
|
||||
void newOutput(QString output);
|
||||
void PM3StatedChanged(bool st, const QString& info = "");
|
||||
void newOutput(const QString& output);
|
||||
void changeClientType(Util::ClientType);
|
||||
};
|
||||
|
||||
#endif // PM3PROCESS_H
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#include "util.h"
|
||||
|
||||
Util::ClientType Util::clientType = CLIENTTYPE_OFFICIAL;
|
||||
|
||||
Util::Util(QObject *parent) : QObject(parent)
|
||||
{
|
||||
isRequiringOutput = false;
|
||||
requiredOutput = new QString();
|
||||
timeStamp = QTime::currentTime();
|
||||
qRegisterMetaType<Util::ClientType>("Util::ClientType");
|
||||
}
|
||||
|
||||
void Util::processOutput(QString output)
|
||||
void Util::processOutput(const QString& output)
|
||||
{
|
||||
// qDebug() << "Util::processOutput:" << output;
|
||||
if(isRequiringOutput)
|
||||
@@ -18,35 +21,102 @@ void Util::processOutput(QString output)
|
||||
emit refreshOutput(output);
|
||||
}
|
||||
|
||||
void Util::execCMD(QString cmd)
|
||||
void Util::execCMD(const QString& cmd)
|
||||
{
|
||||
qDebug() << cmd;
|
||||
qDebug() << "executing: " << cmd;
|
||||
if(isRunning)
|
||||
emit write(cmd + "\r\n");
|
||||
}
|
||||
|
||||
QString Util::execCMDWithOutput(QString cmd, unsigned long timeout)
|
||||
QString Util::execCMDWithOutput(const QString& cmd, ReturnTrigger trigger)
|
||||
{
|
||||
// if the trigger is empty, this function will wait trigger.waitTime then return all outputs during the wait time.
|
||||
// otherwise, this function will return empty string if no trigger is detected, or return outputs if any trigger is detected.
|
||||
// the waitTime will be refreshed if the client have new outputs
|
||||
bool isResultFound = false;
|
||||
QRegularExpression re;
|
||||
re.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
|
||||
|
||||
if(!isRunning)
|
||||
return "";
|
||||
QTime currTime = QTime::currentTime();
|
||||
QTime targetTime = QTime::currentTime().addMSecs(timeout);
|
||||
QTime targetTime = QTime::currentTime().addMSecs(trigger.waitTime);
|
||||
isRequiringOutput = true;
|
||||
requiredOutput->clear();
|
||||
execCMD(cmd);
|
||||
while( QTime::currentTime() < targetTime)
|
||||
while(QTime::currentTime() < targetTime)
|
||||
{
|
||||
if(!isRunning)
|
||||
break;
|
||||
QApplication::processEvents();
|
||||
if(timeStamp > currTime)
|
||||
// qDebug() << "currOutput:" << *requiredOutput;
|
||||
for(QString otpt : trigger.expectedOutputs)
|
||||
{
|
||||
re.setPattern(otpt);
|
||||
isResultFound = re.match(*requiredOutput).hasMatch();
|
||||
if(isResultFound)
|
||||
{
|
||||
qDebug() << "output Matched: " << *requiredOutput;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isResultFound)
|
||||
{
|
||||
delay(200);
|
||||
break;
|
||||
}
|
||||
if(timeStamp > currTime) //has new output
|
||||
{
|
||||
currTime = timeStamp;
|
||||
targetTime = timeStamp.addMSecs(timeout);
|
||||
targetTime = timeStamp.addMSecs(trigger.waitTime);
|
||||
}
|
||||
}
|
||||
isRequiringOutput = false;
|
||||
return *requiredOutput;
|
||||
return (isResultFound || trigger.expectedOutputs.isEmpty() ? *requiredOutput : "");
|
||||
}
|
||||
|
||||
void Util::delay(unsigned int msec)
|
||||
{
|
||||
QTime timer = QTime::currentTime().addMSecs(msec);
|
||||
while( QTime::currentTime() < timer )
|
||||
while(QTime::currentTime() < timer)
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
}
|
||||
|
||||
Util::ClientType Util::getClientType()
|
||||
{
|
||||
return Util::clientType;
|
||||
}
|
||||
|
||||
void Util::setClientType(Util::ClientType clientType)
|
||||
{
|
||||
Util::clientType = clientType;
|
||||
}
|
||||
|
||||
void Util::setRunningState(bool st)
|
||||
{
|
||||
this->isRunning = st;
|
||||
}
|
||||
|
||||
bool Util::chooseLanguage(QSettings* guiSettings, QMainWindow* window)
|
||||
{
|
||||
// make sure the GUISettings is not in any group
|
||||
QSettings* langSettings = new QSettings("lang/languages.ini", QSettings::IniFormat);
|
||||
QMap<QString, QString> langMap;
|
||||
langSettings->setIniCodec("UTF-8");
|
||||
langSettings->beginGroup("Languages");
|
||||
QStringList langList = langSettings->allKeys();
|
||||
for(int i = 0; i < langList.size(); i++)
|
||||
langMap.insert(langSettings->value(langList[i]).toString(), langList[i]);
|
||||
langSettings->endGroup();
|
||||
delete langSettings;
|
||||
bool isOk = false;
|
||||
QString selectedText = QInputDialog::getItem(window, "", "Choose a language:", langMap.keys(), 0, false, &isOk);
|
||||
if(isOk)
|
||||
{
|
||||
guiSettings->beginGroup("lang");
|
||||
guiSettings->setValue("language", langMap[selectedText]);
|
||||
guiSettings->endGroup();
|
||||
guiSettings->sync();
|
||||
}
|
||||
return isOk;
|
||||
}
|
||||
|
||||
@@ -8,26 +8,67 @@
|
||||
#include <QApplication>
|
||||
#include <QTime>
|
||||
#include <QTimer>
|
||||
#include <QMetaType>
|
||||
#include <QRegularExpression>
|
||||
#include <QSettings>
|
||||
#include <QMainWindow>
|
||||
#include <QInputDialog>
|
||||
|
||||
class Util : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ClientType
|
||||
{
|
||||
CLIENTTYPE_OFFICIAL,
|
||||
CLIENTTYPE_ICEMAN,
|
||||
};
|
||||
|
||||
struct ReturnTrigger
|
||||
{
|
||||
unsigned long waitTime;
|
||||
QStringList expectedOutputs;
|
||||
ReturnTrigger(unsigned long time)
|
||||
{
|
||||
waitTime = time;
|
||||
expectedOutputs = QStringList();
|
||||
}
|
||||
ReturnTrigger(const QStringList& outputs)
|
||||
{
|
||||
waitTime = 10000;
|
||||
expectedOutputs = outputs;
|
||||
}
|
||||
ReturnTrigger(unsigned long time, const QStringList& outputs)
|
||||
{
|
||||
waitTime = time;
|
||||
expectedOutputs = outputs;
|
||||
}
|
||||
};
|
||||
|
||||
Q_ENUM(Util::ClientType)
|
||||
|
||||
explicit Util(QObject *parent = nullptr);
|
||||
|
||||
void execCMD(QString cmd);
|
||||
QString execCMDWithOutput(QString cmd, unsigned long timeout = 2000);
|
||||
void execCMD(const QString& cmd);
|
||||
QString execCMDWithOutput(const QString& cmd, ReturnTrigger trigger = 10000);
|
||||
void delay(unsigned int msec);
|
||||
static ClientType getClientType();
|
||||
static const int rawTabIndex = 1;
|
||||
static bool chooseLanguage(QSettings *guiSettings, QMainWindow *window);
|
||||
public slots:
|
||||
void processOutput(QString output);
|
||||
void processOutput(const QString& output);
|
||||
static void setClientType(Util::ClientType clientType);
|
||||
void setRunningState(bool st);
|
||||
|
||||
private:
|
||||
bool isRequiringOutput;
|
||||
bool isRunning;
|
||||
QString* requiredOutput;
|
||||
QTime timeStamp;
|
||||
static ClientType clientType;
|
||||
signals:
|
||||
void refreshOutput(const QString& output);
|
||||
void write(QString data);
|
||||
void write(QString data); // connected to PM3Process::write(QString data);
|
||||
};
|
||||
|
||||
#endif // UTIL_H
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[Languages]
|
||||
en_US=English
|
||||
zh_CN=简体中文
|
||||
@@ -4,54 +4,50 @@
|
||||
#include <QSettings>
|
||||
#include <QTranslator>
|
||||
#include <QMessageBox>
|
||||
#include <QInputDialog>
|
||||
#include <QTextCodec>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
|
||||
QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
|
||||
QVariant lang = settings->value("lang", "null");
|
||||
if(lang == "null")
|
||||
settings->setIniCodec("UTF-8");
|
||||
settings->beginGroup("lang");
|
||||
QString currLang = settings->value("language", "").toString();
|
||||
settings->endGroup();
|
||||
if(currLang == "")
|
||||
{
|
||||
#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")
|
||||
if(Util::chooseLanguage(settings, &w))
|
||||
{
|
||||
settings->beginGroup("lang");
|
||||
currLang = settings->value("language", "").toString();
|
||||
settings->endGroup();
|
||||
}
|
||||
else
|
||||
currLang = "en_US";
|
||||
}
|
||||
currLang = "lang/" + currLang;
|
||||
#ifdef Q_OS_WIN
|
||||
lang = "lang/en_US.qm";
|
||||
currLang += ".qm";
|
||||
#else
|
||||
lang = "lang/en_US.ts";
|
||||
currLang += ".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()))
|
||||
if(translator->load(currLang))
|
||||
{
|
||||
a.installTranslator(translator);
|
||||
settings->setValue("lang", lang);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(&w, "Error", "Can't load " + lang.toString() + " as translation file.");
|
||||
QMessageBox::information(&w, "Error", "Can't load " + currLang + " as translation file.");
|
||||
}
|
||||
delete settings;
|
||||
w.initUI();
|
||||
w.show();
|
||||
return a.exec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
#include "ui_mainwindow.h"
|
||||
#include "ui/mf_attack_hardnesteddialog.h"
|
||||
#include "ui/mf_uid_parameterdialog.h"
|
||||
#include "ui/mf_sim_simdialog.h"
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QRegExp>
|
||||
#include <QRegularExpression>
|
||||
#include <QMessageBox>
|
||||
class Mifare : public QObject
|
||||
{
|
||||
@@ -16,18 +17,11 @@ class Mifare : public QObject
|
||||
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 KeyType
|
||||
{
|
||||
KEY_A = 'A',
|
||||
KEY_B = 'B',
|
||||
};
|
||||
|
||||
enum DataType
|
||||
{
|
||||
@@ -38,73 +32,85 @@ public:
|
||||
|
||||
struct CardType
|
||||
{
|
||||
int type;
|
||||
int sectors;
|
||||
int blocks;
|
||||
int blk[40];
|
||||
int blks[40];
|
||||
quint8 type;
|
||||
quint8 sector_size;
|
||||
quint16 block_size;
|
||||
quint8 blk[40];
|
||||
quint8 blks[40];
|
||||
QString typeText;
|
||||
};
|
||||
|
||||
const CardType card_mini =
|
||||
enum AccessType
|
||||
{
|
||||
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}
|
||||
ACC_NEVER = 0,
|
||||
ACC_KEY_A = 1,
|
||||
ACC_KEY_B = 2,
|
||||
ACC_KEY_AB = 3,
|
||||
};
|
||||
|
||||
void data_clearData();
|
||||
void data_clearKey();
|
||||
bool data_isKeyValid(const QString &key);
|
||||
Mifare::DataType data_isDataValid(QString data);
|
||||
enum TargetType
|
||||
{
|
||||
TARGET_MIFARE,
|
||||
TARGET_UID,
|
||||
TARGET_EMULATOR,
|
||||
};
|
||||
|
||||
static const CardType card_mini;
|
||||
static const CardType card_1k;
|
||||
static const CardType card_2k;
|
||||
static const CardType card_4k;
|
||||
|
||||
static const AccessType dataCondition[8][4];
|
||||
static const AccessType trailerReadCondition[8][3];
|
||||
static const AccessType trailerWriteCondition[8][3];
|
||||
|
||||
QString info(bool isRequiringOutput = false);
|
||||
void chk();
|
||||
void nested();
|
||||
void darkside();
|
||||
void hardnested();
|
||||
void sniff();
|
||||
void sniff14a();
|
||||
void list();
|
||||
void readOne(TargetType targetType = TARGET_MIFARE);
|
||||
void readSelected(TargetType targetType = TARGET_MIFARE);
|
||||
void writeOne(TargetType targetType = TARGET_MIFARE);
|
||||
void writeSelected(TargetType targetType = TARGET_MIFARE);
|
||||
void dump();
|
||||
void restore();
|
||||
|
||||
void data_clearData(bool clearAll = true);
|
||||
void data_clearKey(bool clearAll = true);
|
||||
static bool data_isKeyValid(const QString& key);
|
||||
static Mifare::DataType data_isDataValid(const QString& data);
|
||||
void data_syncWithDataWidget(bool syncAll = true, int block = 0);
|
||||
void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, bool isKeyA = true);
|
||||
void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, KeyType keyType = KEY_A);
|
||||
|
||||
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_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);
|
||||
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 data_setData(int block, const QString& data);
|
||||
void data_setKey(int sector, KeyType keyType, const QString& key);
|
||||
void lockC();
|
||||
void wipeE();
|
||||
void simulate();
|
||||
void loadSniff(const QString& file);
|
||||
void saveSniff(const QString& file);
|
||||
void data_fillKeys();
|
||||
|
||||
static QList<quint8> data_getACBits(const QString& text);
|
||||
static int data_b2s(int block);
|
||||
static bool data_isACBitsValid(const QString& text, QList<quint8> *returnHalfBytes = nullptr);
|
||||
public slots:
|
||||
signals:
|
||||
|
||||
@@ -116,11 +122,14 @@ private:
|
||||
QStringList* keyAList;
|
||||
QStringList* keyBList;
|
||||
QStringList* dataList;
|
||||
QRegExp* dataPattern;
|
||||
QRegExp* chkKeyPattern;
|
||||
QRegExp* nestedKeyPattern;
|
||||
QRegExp* UIDPattern;
|
||||
QString bin2text(const QByteArray &buff, int start, int length);
|
||||
QRegularExpression* dataPattern;
|
||||
QRegularExpression* keyPattern_res;
|
||||
QRegularExpression* keyPattern;
|
||||
QString bin2text(const QByteArray& buff, int start, int length);
|
||||
|
||||
QString _readblk(int blockId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
|
||||
QStringList _readsec(int sectorId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
|
||||
bool _writeblk(int blockId, KeyType keyType, const QString& key, const QString& data, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
|
||||
};
|
||||
|
||||
#endif // MIFARE_H
|
||||
|
||||
@@ -1,29 +1,50 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
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, [ = ]() {
|
||||
currVersion = new QAction("Ver: " + QApplication::applicationVersion().section('.', 0, -2), this); // ignore the 4th version number
|
||||
checkUpdate = new QAction(tr("Check Update"), this);
|
||||
connect(myInfo, &QAction::triggered, [ = ]()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl("https://github.com/wh201906"));
|
||||
});
|
||||
connect(checkUpdate, &QAction::triggered, [ = ]()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl("https://github.com/wh201906/Proxmark3GUI/releases"));
|
||||
});
|
||||
this->addAction(myInfo);
|
||||
this->addAction(currVersion);
|
||||
this->addAction(checkUpdate);
|
||||
|
||||
settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
|
||||
settings->setIniCodec("UTF-8");
|
||||
|
||||
pm3Thread = new QThread(this);
|
||||
pm3 = new PM3Process(pm3Thread);
|
||||
// pm3->moveToThread(pm3Thread);
|
||||
// pm3->init();
|
||||
pm3Thread->start();
|
||||
pm3state = false;
|
||||
clientWorkingDir = new QDir;
|
||||
|
||||
util = new Util(this);
|
||||
mifare = new Mifare(ui, util, this);
|
||||
|
||||
keyEventFilter = new MyEventFilter(QEvent::KeyRelease);
|
||||
resizeEventFilter = new MyEventFilter(QEvent::Resize);
|
||||
|
||||
// hide unused tabs
|
||||
ui->funcTab->removeTab(1);
|
||||
ui->funcTab->removeTab(1);
|
||||
|
||||
portSearchTimer = new QTimer(this);
|
||||
portSearchTimer->setInterval(2000);
|
||||
connect(portSearchTimer, &QTimer::timeout, this, &MainWindow::on_portSearchTimer_timeout);
|
||||
portSearchTimer->start();
|
||||
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@@ -46,63 +67,89 @@ void MainWindow::initUI() // will be called by main.app
|
||||
|
||||
// ******************** basic functions ********************
|
||||
|
||||
void MainWindow::on_PM3_refreshPortButton_clicked()
|
||||
void MainWindow::on_portSearchTimer_timeout()
|
||||
{
|
||||
ui->PM3_portBox->clear();
|
||||
ui->PM3_portBox->addItem("");
|
||||
QSerialPort serial;
|
||||
QStringList serialList;
|
||||
QStringList newPortList;
|
||||
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();
|
||||
// qDebug() << info.isBusy() << info.isNull() << info.portName() << info.description();
|
||||
if(!info.isNull())
|
||||
newPortList << info.portName();
|
||||
}
|
||||
}
|
||||
foreach(QString port, serialList)
|
||||
if(newPortList != portList) // update PM3_portBox when available ports changed
|
||||
{
|
||||
ui->PM3_portBox->addItem(port);
|
||||
portList = newPortList;
|
||||
ui->PM3_portBox->clear();
|
||||
ui->PM3_portBox->addItems(portList);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
QStringList args = ui->Set_Client_startArgsEdit->text().replace("<port>", port).split(' ');
|
||||
saveClientPath(ui->PM3_pathEdit->text());
|
||||
|
||||
QProcess envSetProcess;
|
||||
QFileInfo envScriptPath(ui->Set_Client_envScriptEdit->text());
|
||||
if(envScriptPath.exists())
|
||||
{
|
||||
qDebug() << envScriptPath.absoluteFilePath();
|
||||
#ifdef Q_OS_WIN
|
||||
// cmd /c "<path>">>nul && set
|
||||
envSetProcess.start("cmd /c \"" + envScriptPath.absoluteFilePath() + "\">>nul && set");
|
||||
#else
|
||||
// sh -c '. "<path>">>/dev/null && env'
|
||||
envSetProcess.start("sh -c \' . \"" + envScriptPath.absoluteFilePath() + "\">>/dev/null && env");
|
||||
#endif
|
||||
envSetProcess.waitForReadyRead(10000);
|
||||
clientEnv = QString(envSetProcess.readAll()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
|
||||
// qDebug() << "Get Env List" << clientEnv;
|
||||
}
|
||||
else
|
||||
clientEnv.clear();
|
||||
emit setProcEnv(&clientEnv);
|
||||
|
||||
clientWorkingDir->setPath(QApplication::applicationDirPath());
|
||||
qDebug() << clientWorkingDir->absolutePath();
|
||||
clientWorkingDir->mkpath(ui->Set_Client_workingDirEdit->text());
|
||||
qDebug() << clientWorkingDir->absolutePath();
|
||||
clientWorkingDir->cd(ui->Set_Client_workingDirEdit->text());
|
||||
qDebug() << clientWorkingDir->absolutePath();
|
||||
emit setWorkingDir(clientWorkingDir->absolutePath());
|
||||
|
||||
emit connectPM3(ui->PM3_pathEdit->text(), port, args);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPM3StateChanged(bool st, QString info)
|
||||
void MainWindow::onPM3StateChanged(bool st, const QString& info)
|
||||
{
|
||||
pm3state = st;
|
||||
setState(st);
|
||||
if(st == true)
|
||||
{
|
||||
portSearchTimer->stop();
|
||||
setStatusBar(PM3VersionBar, info);
|
||||
setStatusBar(connectStatusBar, tr("Connected"));
|
||||
}
|
||||
else
|
||||
{
|
||||
portSearchTimer->start();
|
||||
setStatusBar(PM3VersionBar, "");
|
||||
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)
|
||||
@@ -112,17 +159,31 @@ void MainWindow::refreshOutput(const QString& output)
|
||||
ui->Raw_outputEdit->moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
void MainWindow::refreshCMD(const QString& cmd)
|
||||
void MainWindow::on_stopButton_clicked()
|
||||
{
|
||||
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);
|
||||
if(!pm3state)
|
||||
on_PM3_disconnectButton_clicked();
|
||||
else
|
||||
{
|
||||
on_PM3_disconnectButton_clicked();
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
util->delay(200);
|
||||
if(!pm3state)
|
||||
break;
|
||||
}
|
||||
emit reconnectPM3();
|
||||
}
|
||||
}
|
||||
|
||||
// *********************************************************
|
||||
|
||||
// ******************** raw command ********************
|
||||
|
||||
void MainWindow::on_Raw_CMDEdit_textChanged(const QString &arg1)
|
||||
{
|
||||
stashedCMDEditText = arg1;
|
||||
}
|
||||
|
||||
void MainWindow::on_Raw_sendCMDButton_clicked()
|
||||
{
|
||||
util->execCMD(ui->Raw_CMDEdit->text());
|
||||
@@ -167,41 +228,184 @@ void MainWindow::sendMSG() // send command when pressing Enter
|
||||
on_Raw_sendCMDButton_clicked();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::refreshCMD(const QString& cmd)
|
||||
{
|
||||
ui->Raw_CMDEdit->blockSignals(true);
|
||||
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);
|
||||
stashedCMDEditText = cmd;
|
||||
stashedIndex = -1;
|
||||
ui->Raw_CMDEdit->blockSignals(false);
|
||||
}
|
||||
|
||||
void MainWindow::on_Raw_CMDEdit_keyPressed(QObject* obj_addr, QEvent& event)
|
||||
{
|
||||
if(obj_addr == ui->Raw_CMDEdit && event.type() == QEvent::KeyRelease)
|
||||
{
|
||||
QKeyEvent& keyEvent = static_cast<QKeyEvent&>(event);
|
||||
if(keyEvent.key() == Qt::Key_Up)
|
||||
{
|
||||
if(stashedIndex > 0)
|
||||
stashedIndex--;
|
||||
else if(stashedIndex == -1)
|
||||
stashedIndex = ui->Raw_CMDHistoryWidget->count() - 1;
|
||||
}
|
||||
else if(keyEvent.key() == Qt::Key_Down)
|
||||
{
|
||||
if(stashedIndex < ui->Raw_CMDHistoryWidget->count() - 1 && stashedIndex != -1)
|
||||
stashedIndex++;
|
||||
else if(stashedIndex == ui->Raw_CMDHistoryWidget->count() - 1)
|
||||
stashedIndex = -1;
|
||||
}
|
||||
if(keyEvent.key() == Qt::Key_Up || keyEvent.key() == Qt::Key_Down)
|
||||
{
|
||||
ui->Raw_CMDEdit->blockSignals(true);
|
||||
if(stashedIndex == -1)
|
||||
ui->Raw_CMDEdit->setText(stashedCMDEditText);
|
||||
else
|
||||
ui->Raw_CMDEdit->setText(ui->Raw_CMDHistoryWidget->item(stashedIndex)->text());
|
||||
ui->Raw_CMDEdit->blockSignals(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// *****************************************************
|
||||
|
||||
// ******************** mifare ********************
|
||||
void MainWindow::MF_onTypeChanged(int id, bool st)
|
||||
void MainWindow::on_MF_keyWidget_resized(QObject* obj_addr, QEvent& event)
|
||||
{
|
||||
typeBtnGroup->blockSignals(true);
|
||||
qDebug() << id << typeBtnGroup->checkedId();
|
||||
if(obj_addr == ui->MF_keyWidget && event.type() == QEvent::Resize)
|
||||
{
|
||||
QTableWidget* widget = (QTableWidget*)obj_addr;
|
||||
int keyItemWidth = widget->width();
|
||||
keyItemWidth -= widget->verticalScrollBar()->width();
|
||||
keyItemWidth -= 2 * widget->frameWidth();
|
||||
keyItemWidth -= widget->horizontalHeader()->sectionSize(0);
|
||||
widget->horizontalHeader()->resizeSection(1, keyItemWidth / 2);
|
||||
widget->horizontalHeader()->resizeSection(2, keyItemWidth / 2);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::MF_onMFCardTypeChanged(int id, bool st)
|
||||
{
|
||||
MFCardTypeBtnGroup->blockSignals(true);
|
||||
qDebug() << id << MFCardTypeBtnGroup->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);
|
||||
int result;
|
||||
if(id > MFCardTypeBtnGroup->checkedId()) // id is specified in uiInit() with a proper order, so I can compare the size by id.
|
||||
{
|
||||
result = QMessageBox::question(this, tr("Info"), tr("Some of the data and key will be cleared.") + "\n" + tr("Continue?"), QMessageBox::Yes | QMessageBox::No);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = QMessageBox::Yes;
|
||||
}
|
||||
if(result == QMessageBox::Yes)
|
||||
{
|
||||
qDebug() << "Yes";
|
||||
mifare->setCardType(typeBtnGroup->checkedId());
|
||||
mifare->setCardType(MFCardTypeBtnGroup->checkedId());
|
||||
MF_widgetReset();
|
||||
mifare->data_syncWithDataWidget();
|
||||
mifare->data_syncWithKeyWidget();
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "No";
|
||||
typeBtnGroup->button(id)->setChecked(true);
|
||||
MFCardTypeBtnGroup->button(id)->setChecked(true);
|
||||
}
|
||||
}
|
||||
typeBtnGroup->blockSignals(false);
|
||||
MFCardTypeBtnGroup->blockSignals(false);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_data2KeyBotton_clicked()
|
||||
void MainWindow::on_MF_selectAllBox_stateChanged(int arg1)
|
||||
{
|
||||
ui->MF_dataWidget->blockSignals(true);
|
||||
ui->MF_selectAllBox->blockSignals(true);
|
||||
ui->MF_selectTrailerBox->blockSignals(true);
|
||||
if(arg1 == Qt::PartiallyChecked)
|
||||
{
|
||||
ui->MF_selectAllBox->setTristate(false);
|
||||
ui->MF_selectAllBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
for(int i = 0; i < mifare->cardType.block_size; i++)
|
||||
{
|
||||
ui->MF_dataWidget->item(i, 1)->setCheckState(ui->MF_selectAllBox->checkState());
|
||||
}
|
||||
for(int i = 0; i < mifare->cardType.sector_size; i++)
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(ui->MF_selectAllBox->checkState());
|
||||
}
|
||||
ui->MF_selectTrailerBox->setCheckState(ui->MF_selectAllBox->checkState());
|
||||
ui->MF_dataWidget->blockSignals(false);
|
||||
ui->MF_selectAllBox->blockSignals(false);
|
||||
ui->MF_selectTrailerBox->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_MF_selectTrailerBox_stateChanged(int arg1)
|
||||
{
|
||||
int selectedSubBlocks = 0;
|
||||
|
||||
ui->MF_dataWidget->blockSignals(true);
|
||||
ui->MF_selectAllBox->blockSignals(true);
|
||||
ui->MF_selectTrailerBox->blockSignals(true);
|
||||
if(arg1 == Qt::PartiallyChecked)
|
||||
{
|
||||
ui->MF_selectTrailerBox->setTristate(false);
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
for(int i = 0; i < mifare->cardType.sector_size; i++)
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[i] + mifare->cardType.blk[i] - 1, 1)->setCheckState(ui->MF_selectTrailerBox->checkState());
|
||||
selectedSubBlocks = 0;
|
||||
for(int j = 0; j < mifare->cardType.blk[i]; j++)
|
||||
{
|
||||
if(ui->MF_dataWidget->item(j + mifare->cardType.blks[i], 1)->checkState() == Qt::Checked)
|
||||
selectedSubBlocks++;
|
||||
}
|
||||
if(selectedSubBlocks == 0)
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else if(selectedSubBlocks == mifare->cardType.blk[i])
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
}
|
||||
|
||||
ui->MF_dataWidget->blockSignals(false);
|
||||
ui->MF_selectAllBox->blockSignals(false);
|
||||
ui->MF_selectTrailerBox->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_MF_data2KeyButton_clicked()
|
||||
{
|
||||
mifare->data_data2Key();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_key2DataBotton_clicked()
|
||||
void MainWindow::on_MF_key2DataButton_clicked()
|
||||
{
|
||||
mifare->data_key2Data();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_fillKeysButton_clicked()
|
||||
{
|
||||
mifare->data_fillKeys();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_trailerDecoderButton_clicked()
|
||||
{
|
||||
decDialog = new MF_trailerDecoderDialog(this);
|
||||
decDialog->show();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_fontButton_clicked()
|
||||
{
|
||||
bool isOK = false;
|
||||
@@ -216,8 +420,100 @@ void MainWindow::on_MF_fontButton_clicked()
|
||||
|
||||
void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
|
||||
{
|
||||
ui->MF_dataWidget->blockSignals(true);
|
||||
ui->MF_selectAllBox->blockSignals(true);
|
||||
ui->MF_selectTrailerBox->blockSignals(true);
|
||||
if(item->column() == 0)
|
||||
{
|
||||
int selectedSectors = 0;
|
||||
for(int i = 0; i < mifare->cardType.blk[Mifare::data_b2s(item->row())]; i++)
|
||||
{
|
||||
ui->MF_dataWidget->item(i + item->row(), 1)->setCheckState(item->checkState());
|
||||
qDebug() << i << mifare->cardType.blk[item->row()] << i + item->row() << ui->MF_dataWidget->item(i + item->row(), 1)->text();
|
||||
}
|
||||
for(int i = 0; i < mifare->cardType.sector_size; i++)
|
||||
{
|
||||
if(ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->checkState() == Qt::Checked)
|
||||
{
|
||||
selectedSectors++;
|
||||
}
|
||||
}
|
||||
if(selectedSectors == 0)
|
||||
{
|
||||
ui->MF_selectAllBox->setCheckState(Qt::Unchecked);
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else if(selectedSectors == mifare->cardType.sector_size)
|
||||
{
|
||||
ui->MF_selectAllBox->setCheckState(Qt::Checked);
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->MF_selectAllBox->setCheckState(Qt::PartiallyChecked);
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
}
|
||||
else if(item->column() == 1)
|
||||
{
|
||||
int selectedSubBlocks = 0;
|
||||
int selectedBlocks = 0;
|
||||
int selectedTrailers = 0;
|
||||
|
||||
if(item->column() == 2)
|
||||
for(int i = 0; i < mifare->cardType.block_size; i++)
|
||||
{
|
||||
if(ui->MF_dataWidget->item(i, 1)->checkState() == Qt::Checked)
|
||||
selectedBlocks++;
|
||||
}
|
||||
for(int i = 0; i < mifare->cardType.blk[Mifare::data_b2s(item->row())]; i++)
|
||||
{
|
||||
if(ui->MF_dataWidget->item(i + mifare->cardType.blks[Mifare::data_b2s(item->row())], 1)->checkState() == Qt::Checked)
|
||||
selectedSubBlocks++;
|
||||
}
|
||||
for(int i = 0; i < mifare->cardType.sector_size; i++)
|
||||
{
|
||||
int targetBlock = mifare->cardType.blks[i] + mifare->cardType.blk[i] - 1;
|
||||
if(ui->MF_dataWidget->item(targetBlock, 1)->checkState() == Qt::Checked)
|
||||
selectedTrailers++;
|
||||
}
|
||||
if(selectedBlocks == 0)
|
||||
{
|
||||
ui->MF_selectAllBox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else if(selectedBlocks == mifare->cardType.block_size)
|
||||
{
|
||||
ui->MF_selectAllBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->MF_selectAllBox->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
if(selectedSubBlocks == 0)
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[Mifare::data_b2s(item->row())], 0)->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else if(selectedSubBlocks == mifare->cardType.blk[Mifare::data_b2s(item->row())])
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[Mifare::data_b2s(item->row())], 0)->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[Mifare::data_b2s(item->row())], 0)->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
if(selectedTrailers == 0)
|
||||
{
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
else if(selectedTrailers == mifare->cardType.sector_size)
|
||||
{
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
}
|
||||
else if(item->column() == 2)
|
||||
{
|
||||
QString data = item->text().replace(" ", "").toUpper();
|
||||
if(data == "" || mifare->data_isDataValid(data) == Mifare::DATA_NOSPACE)
|
||||
@@ -230,6 +526,9 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
|
||||
}
|
||||
mifare->data_syncWithDataWidget(false, item->row());
|
||||
}
|
||||
ui->MF_dataWidget->blockSignals(false);
|
||||
ui->MF_selectAllBox->blockSignals(false);
|
||||
ui->MF_selectTrailerBox->blockSignals(false);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item)
|
||||
@@ -239,26 +538,26 @@ void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item)
|
||||
QString key = item->text().replace(" ", "").toUpper();
|
||||
if(key == "" || mifare->data_isKeyValid(key))
|
||||
{
|
||||
mifare->data_setKey(item->row(), true, key);
|
||||
mifare->data_setKey(item->row(), Mifare::KEY_A, 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);
|
||||
mifare->data_syncWithKeyWidget(false, item->row(), Mifare::KEY_A);
|
||||
}
|
||||
else if(item->column() == 2)
|
||||
{
|
||||
QString key = item->text().replace(" ", "");
|
||||
QString key = item->text().replace(" ", "").toUpper();
|
||||
if(key == "" || mifare->data_isKeyValid(key))
|
||||
{
|
||||
mifare->data_setKey(item->row(), false, key);
|
||||
mifare->data_setKey(item->row(), Mifare::KEY_B, 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);
|
||||
mifare->data_syncWithKeyWidget(false, item->row(), Mifare::KEY_B);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,31 +668,31 @@ void MainWindow::on_MF_Attack_hardnestedButton_clicked()
|
||||
mifare->hardnested();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_RW_readAllButton_clicked()
|
||||
void MainWindow::on_MF_RW_readSelectedButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->readAll();
|
||||
mifare->readSelected(Mifare::TARGET_MIFARE);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_RW_readBlockButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->read();
|
||||
mifare->readOne(Mifare::TARGET_MIFARE);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_RW_writeBlockButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->write();
|
||||
mifare->writeOne();
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_RW_writeAllButton_clicked()
|
||||
void MainWindow::on_MF_RW_writeSelectedButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->writeAll();
|
||||
mifare->writeSelected(Mifare::TARGET_MIFARE);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
@@ -407,31 +706,31 @@ void MainWindow::on_MF_RW_restoreButton_clicked()
|
||||
mifare->restore();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_UID_readAllButton_clicked()
|
||||
void MainWindow::on_MF_UID_readSelectedButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->readAllC();
|
||||
mifare->readSelected(Mifare::TARGET_UID);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_UID_readBlockButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->readC();
|
||||
mifare->readOne(Mifare::TARGET_UID);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_UID_writeAllButton_clicked()
|
||||
void MainWindow::on_MF_UID_writeSelectedButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->writeAllC();
|
||||
mifare->writeSelected(Mifare::TARGET_UID);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_UID_writeBlockButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->writeC();
|
||||
mifare->writeOne(Mifare::TARGET_UID);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
@@ -473,6 +772,74 @@ void MainWindow::on_MF_UID_lockButton_clicked()
|
||||
mifare->lockC();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sim_readSelectedButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->readSelected(Mifare::TARGET_EMULATOR);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sim_writeSelectedButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->writeSelected(Mifare::TARGET_EMULATOR);
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sim_clearButton_clicked()
|
||||
{
|
||||
mifare->wipeE();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sim_simButton_clicked()
|
||||
{
|
||||
mifare->simulate();
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sniff_loadButton_clicked() // use a tmp file to support complicated path
|
||||
{
|
||||
QString title = "";
|
||||
QString filename = "";
|
||||
|
||||
title = tr("Plz select the trace file:");
|
||||
filename = QFileDialog::getOpenFileName(this, title, "./", tr("Trace Files(*.trc);;All Files(*.*)"));
|
||||
qDebug() << filename;
|
||||
if(filename != "")
|
||||
{
|
||||
QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc";
|
||||
if(QFile::copy(filename, "./" + tmpFile))
|
||||
{
|
||||
mifare->loadSniff(tmpFile);
|
||||
QFile::remove("./" + tmpFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(this, tr("Info"), tr("Failed to open") + "\n" + filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sniff_saveButton_clicked()
|
||||
{
|
||||
QString title = "";
|
||||
QString filename = "";
|
||||
|
||||
title = tr("Plz select the location to save trace file:");
|
||||
filename = QFileDialog::getSaveFileName(this, title, "./", tr("Trace Files(*.trc)"));
|
||||
qDebug() << filename;
|
||||
if(filename != "")
|
||||
{
|
||||
QString tmpFile = "tmp" + QString::number(QDateTime::currentDateTime().toTime_t()) + ".trc";
|
||||
mifare->saveSniff(tmpFile);
|
||||
if(!QFile::copy("./" + tmpFile, filename))
|
||||
{
|
||||
QMessageBox::information(this, tr("Info"), tr("Failed to save to") + "\n" + filename);
|
||||
}
|
||||
QFile::remove("./" + tmpFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sniff_sniffButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
@@ -480,6 +847,13 @@ void MainWindow::on_MF_Sniff_sniffButton_clicked()
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_14aSniff_snoopButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->sniff14a();
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_MF_Sniff_listButton_clicked()
|
||||
{
|
||||
mifare->list();
|
||||
@@ -487,16 +861,23 @@ void MainWindow::on_MF_Sniff_listButton_clicked()
|
||||
|
||||
void MainWindow::MF_widgetReset()
|
||||
{
|
||||
int secs = mifare->cardType.sectors;
|
||||
int blks = mifare->cardType.blocks;
|
||||
int secs = mifare->cardType.sector_size;
|
||||
int blks = mifare->cardType.block_size;
|
||||
QBrush trailerItemForeColor = QBrush(QColor(0, 160, 255));
|
||||
ui->MF_RW_blockBox->clear();
|
||||
ui->MF_keyWidget->setRowCount(secs);
|
||||
ui->MF_dataWidget->setRowCount(blks);
|
||||
|
||||
ui->MF_dataWidget->blockSignals(true);
|
||||
ui->MF_keyWidget->blockSignals(true);
|
||||
ui->MF_selectAllBox->blockSignals(true);
|
||||
ui->MF_selectTrailerBox->blockSignals(true);
|
||||
|
||||
for(int i = 0; i < blks; i++)
|
||||
{
|
||||
setTableItem(ui->MF_dataWidget, i, 0, "");
|
||||
setTableItem(ui->MF_dataWidget, i, 1, QString::number(i));
|
||||
ui->MF_dataWidget->item(i, 1)->setCheckState(Qt::Checked);
|
||||
setTableItem(ui->MF_dataWidget, i, 2, "");
|
||||
ui->MF_RW_blockBox->addItem(QString::number(i));
|
||||
}
|
||||
@@ -507,7 +888,17 @@ void MainWindow::MF_widgetReset()
|
||||
setTableItem(ui->MF_keyWidget, i, 1, "");
|
||||
setTableItem(ui->MF_keyWidget, i, 2, "");
|
||||
setTableItem(ui->MF_dataWidget, mifare->cardType.blks[i], 0, QString::number(i));
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[i] + mifare->cardType.blk[i] - 1, 2)->setForeground(trailerItemForeColor);
|
||||
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Checked);
|
||||
}
|
||||
ui->MF_dataWidget->item(0, 2)->setForeground(QBrush(QColor(255, 160, 0)));
|
||||
ui->MF_selectAllBox->setCheckState(Qt::Checked);
|
||||
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
|
||||
|
||||
ui->MF_dataWidget->blockSignals(false);
|
||||
ui->MF_keyWidget->blockSignals(false);
|
||||
ui->MF_selectAllBox->blockSignals(false);
|
||||
ui->MF_selectTrailerBox->blockSignals(false);
|
||||
}
|
||||
// ************************************************
|
||||
|
||||
@@ -517,63 +908,122 @@ void MainWindow::MF_widgetReset()
|
||||
void MainWindow::uiInit()
|
||||
{
|
||||
connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG);
|
||||
ui->Raw_CMDEdit->installEventFilter(keyEventFilter);
|
||||
connect(keyEventFilter, &MyEventFilter::eventHappened, this, &MainWindow::on_Raw_CMDEdit_keyPressed);
|
||||
ui->MF_keyWidget->installEventFilter(resizeEventFilter);
|
||||
connect(resizeEventFilter, &MyEventFilter::eventHappened, this, &MainWindow::on_MF_keyWidget_resized);
|
||||
|
||||
connectStatusBar = new QLabel(this);
|
||||
programStatusBar = new QLabel(this);
|
||||
PM3VersionBar = new QLabel(this);
|
||||
stopButton = new QPushButton(this);
|
||||
setStatusBar(connectStatusBar, tr("Not Connected"));
|
||||
setStatusBar(programStatusBar, tr("Idle"));
|
||||
setStatusBar(PM3VersionBar, "");
|
||||
stopButton->setText(tr("Stop"));
|
||||
ui->statusbar->addPermanentWidget(PM3VersionBar, 1);
|
||||
ui->statusbar->addPermanentWidget(connectStatusBar, 1);
|
||||
ui->statusbar->addPermanentWidget(programStatusBar, 1);
|
||||
ui->statusbar->addPermanentWidget(stopButton);
|
||||
|
||||
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_dataWidget->setColumnWidth(0, 55);
|
||||
ui->MF_dataWidget->setColumnWidth(1, 55);
|
||||
|
||||
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);
|
||||
ui->MF_keyWidget->setColumnWidth(0, 45);
|
||||
|
||||
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);
|
||||
MFCardTypeBtnGroup = new QButtonGroup(this);
|
||||
MFCardTypeBtnGroup->addButton(ui->MF_Type_miniButton, 0);
|
||||
MFCardTypeBtnGroup->addButton(ui->MF_Type_1kButton, 1);
|
||||
MFCardTypeBtnGroup->addButton(ui->MF_Type_2kButton, 2);
|
||||
MFCardTypeBtnGroup->addButton(ui->MF_Type_4kButton, 4);
|
||||
connect(MFCardTypeBtnGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MainWindow::MF_onMFCardTypeChanged);
|
||||
|
||||
ui->MF_keyWidget->installEventFilter(this);
|
||||
ui->MF_dataWidget->installEventFilter(this);
|
||||
|
||||
settings->beginGroup("UI_grpbox_preference");
|
||||
|
||||
QStringList boxNames = settings->allKeys();
|
||||
QGroupBox * boxptr;
|
||||
foreach(QString name, boxNames)
|
||||
{
|
||||
boxptr = this->findChild<QGroupBox*>(name);
|
||||
if(boxptr == nullptr)
|
||||
continue;
|
||||
if(settings->value(name, true).toBool())
|
||||
{
|
||||
boxptr->setMaximumHeight(16777215);
|
||||
boxptr->setChecked(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
boxptr->setMaximumHeight(20);
|
||||
boxptr->setChecked(false);
|
||||
}
|
||||
}
|
||||
settings->endGroup();
|
||||
|
||||
settings->beginGroup("Client_Path");
|
||||
ui->PM3_pathEdit->setText(settings->value("path", "proxmark3").toString());
|
||||
settings->endGroup();
|
||||
|
||||
settings->beginGroup("Client_Args");
|
||||
ui->Set_Client_startArgsEdit->setText(settings->value("args", "<port> -f").toString());
|
||||
settings->endGroup();
|
||||
|
||||
settings->beginGroup("Client_forceButtonsEnabled");
|
||||
keepButtonsEnabled = settings->value("state", false).toBool();
|
||||
ui->Set_Client_forceEnabledBox->setChecked(keepButtonsEnabled);
|
||||
settings->endGroup();
|
||||
|
||||
settings->beginGroup("Client_Env");
|
||||
ui->Set_Client_envScriptEdit->setText(settings->value("scriptPath").toString());
|
||||
ui->Set_Client_workingDirEdit->setText(settings->value("workingDir", "../data").toString());
|
||||
settings->endGroup();
|
||||
|
||||
ui->MF_RW_keyTypeBox->addItem("A", Mifare::KEY_A);
|
||||
ui->MF_RW_keyTypeBox->addItem("B", Mifare::KEY_B);
|
||||
|
||||
on_Raw_CMDHistoryBox_stateChanged(Qt::Unchecked);
|
||||
on_PM3_refreshPortButton_clicked();
|
||||
}
|
||||
|
||||
void MainWindow::signalInit()
|
||||
{
|
||||
connect(pm3, &PM3Process::newOutput, util, &Util::processOutput);
|
||||
connect(pm3, &PM3Process::changeClientType, util, &Util::setClientType);
|
||||
connect(util, &Util::refreshOutput, this, &MainWindow::refreshOutput);
|
||||
|
||||
connect(this, &MainWindow::connectPM3, pm3, &PM3Process::connectPM3);
|
||||
connect(this, &MainWindow::reconnectPM3, pm3, &PM3Process::reconnectPM3);
|
||||
connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged);
|
||||
connect(pm3, &PM3Process::PM3StatedChanged, util, &Util::setRunningState);
|
||||
connect(this, &MainWindow::killPM3, pm3, &PM3Process::kill);
|
||||
connect(this, &MainWindow::setProcEnv, pm3, &PM3Process::setProcEnv);
|
||||
connect(this, &MainWindow::setWorkingDir, pm3, &PM3Process::setWorkingDir);
|
||||
|
||||
connect(util, &Util::write, pm3, &PM3Process::write);
|
||||
|
||||
connect(ui->MF_typeGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
|
||||
connect(ui->MF_fileGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
|
||||
connect(ui->MF_RWGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
|
||||
connect(ui->MF_normalGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
|
||||
connect(ui->MF_UIDGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
|
||||
connect(ui->MF_simGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
|
||||
connect(ui->MF_sniffGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
|
||||
|
||||
connect(stopButton, &QPushButton::clicked, this, &MainWindow::on_stopButton_clicked);
|
||||
}
|
||||
|
||||
void MainWindow::setStatusBar(QLabel* target, const QString & text)
|
||||
void MainWindow::setStatusBar(QLabel * target, const QString& text)
|
||||
{
|
||||
if(target == PM3VersionBar)
|
||||
target->setText(tr("HW Version:") + text);
|
||||
@@ -583,14 +1033,14 @@ void MainWindow::setStatusBar(QLabel* target, const QString & text)
|
||||
target->setText(tr("State:") + text);
|
||||
}
|
||||
|
||||
void MainWindow::setTableItem(QTableWidget* widget, int row, int column, const QString& 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
|
||||
bool MainWindow::eventFilter(QObject * watched, QEvent * event) // drag support
|
||||
{
|
||||
if(event->type() == QEvent::DragEnter)
|
||||
{
|
||||
@@ -641,6 +1091,11 @@ void MainWindow::setState(bool st)
|
||||
{
|
||||
setStatusBar(programStatusBar, tr("Idle"));
|
||||
}
|
||||
setButtonsEnabled(st || keepButtonsEnabled);
|
||||
}
|
||||
|
||||
void MainWindow::setButtonsEnabled(bool st)
|
||||
{
|
||||
ui->MF_attackGroupBox->setEnabled(st);
|
||||
ui->MF_normalGroupBox->setEnabled(st);
|
||||
ui->MF_UIDGroupBox->setEnabled(st);
|
||||
@@ -650,4 +1105,78 @@ void MainWindow::setState(bool st)
|
||||
ui->Raw_sendCMDButton->setEnabled(st);
|
||||
}
|
||||
|
||||
void MainWindow::on_GroupBox_clicked(bool checked)
|
||||
{
|
||||
QGroupBox* box = dynamic_cast<QGroupBox*>(sender());
|
||||
|
||||
settings->beginGroup("UI_grpbox_preference");
|
||||
if(checked)
|
||||
{
|
||||
box->setMaximumHeight(16777215);
|
||||
settings->setValue(box->objectName(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
box->setMaximumHeight(20);
|
||||
settings->setValue(box->objectName(), false);
|
||||
}
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void MainWindow::saveClientPath(const QString& path)
|
||||
{
|
||||
settings->beginGroup("Client_Path");
|
||||
settings->setValue("path", path);
|
||||
settings->endGroup();
|
||||
}
|
||||
// ***********************************************
|
||||
|
||||
|
||||
|
||||
void MainWindow::on_MF_Attack_darksideButton_clicked()
|
||||
{
|
||||
setState(false);
|
||||
mifare->darkside();
|
||||
setState(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_Set_Client_startArgsEdit_editingFinished()
|
||||
{
|
||||
settings->beginGroup("Client_Args");
|
||||
settings->setValue("args", ui->Set_Client_startArgsEdit->text());
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void MainWindow::on_Set_Client_forceEnabledBox_stateChanged(int arg1)
|
||||
{
|
||||
settings->beginGroup("Client_forceButtonsEnabled");
|
||||
keepButtonsEnabled = (arg1 == Qt::Checked);
|
||||
settings->setValue("state", keepButtonsEnabled);
|
||||
settings->endGroup();
|
||||
if(keepButtonsEnabled)
|
||||
setButtonsEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_Set_GUI_setLanguageButton_clicked()
|
||||
{
|
||||
Util::chooseLanguage(settings, this);
|
||||
}
|
||||
|
||||
void MainWindow::on_PM3_refreshPortButton_clicked()
|
||||
{
|
||||
on_portSearchTimer_timeout();
|
||||
}
|
||||
|
||||
void MainWindow::on_Set_Client_envScriptEdit_editingFinished()
|
||||
{
|
||||
settings->beginGroup("Client_Env");
|
||||
settings->setValue("scriptPath", ui->Set_Client_envScriptEdit->text());
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void MainWindow::on_Set_Client_saveWorkingDirButton_clicked()
|
||||
{
|
||||
settings->beginGroup("Client_Env");
|
||||
settings->setValue("workingDir", ui->Set_Client_workingDirEdit->text());
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
@@ -16,13 +16,23 @@
|
||||
#include <QMimeData>
|
||||
#include <QAction>
|
||||
#include <QDesktopServices>
|
||||
#include <QGroupBox>
|
||||
#include <QSizePolicy>
|
||||
#include <QSettings>
|
||||
#include <QPushButton>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QScrollBar>
|
||||
#include <QTimer>
|
||||
|
||||
#include "common/myeventfilter.h"
|
||||
#include "common/pm3process.h"
|
||||
#include "module/mifare.h"
|
||||
#include "common/util.h"
|
||||
#include "ui/mf_trailerdecoderdialog.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
namespace Ui
|
||||
{
|
||||
class MainWindow;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
@@ -38,11 +48,13 @@ public:
|
||||
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);
|
||||
void refreshOutput(const QString& output);
|
||||
void refreshCMD(const QString& cmd);
|
||||
void setStatusBar(QLabel* target, const QString& text);
|
||||
void onPM3StateChanged(bool st, const QString& info);
|
||||
void MF_onMFCardTypeChanged(int id, bool st);
|
||||
void on_Raw_CMDEdit_keyPressed(QObject *obj_addr, QEvent &event);
|
||||
void on_MF_keyWidget_resized(QObject *obj_addr, QEvent &event);
|
||||
private slots:
|
||||
|
||||
void on_PM3_connectButton_clicked();
|
||||
@@ -54,7 +66,8 @@ private slots:
|
||||
void on_Raw_clearOutputButton_clicked();
|
||||
|
||||
void sendMSG();
|
||||
void on_PM3_refreshPortButton_clicked();
|
||||
|
||||
void on_portSearchTimer_timeout();
|
||||
|
||||
void on_Raw_CMDHistoryBox_stateChanged(int arg1);
|
||||
|
||||
@@ -72,7 +85,7 @@ private slots:
|
||||
|
||||
void on_MF_Sniff_listButton_clicked();
|
||||
|
||||
void on_MF_RW_readAllButton_clicked();
|
||||
void on_MF_RW_readSelectedButton_clicked();
|
||||
|
||||
void on_MF_RW_readBlockButton_clicked();
|
||||
|
||||
@@ -80,18 +93,17 @@ private slots:
|
||||
|
||||
void on_MF_Attack_infoButton_clicked();
|
||||
|
||||
void on_MF_RW_writeAllButton_clicked();
|
||||
|
||||
void on_MF_RW_writeSelectedButton_clicked();
|
||||
|
||||
void on_MF_RW_dumpButton_clicked();
|
||||
|
||||
void on_MF_RW_restoreButton_clicked();
|
||||
|
||||
void on_MF_UID_readAllButton_clicked();
|
||||
void on_MF_UID_readSelectedButton_clicked();
|
||||
|
||||
void on_MF_UID_readBlockButton_clicked();
|
||||
|
||||
void on_MF_UID_writeAllButton_clicked();
|
||||
void on_MF_UID_writeSelectedButton_clicked();
|
||||
|
||||
void on_MF_UID_writeBlockButton_clicked();
|
||||
|
||||
@@ -99,9 +111,9 @@ private slots:
|
||||
|
||||
void on_MF_File_saveButton_clicked();
|
||||
|
||||
void on_MF_data2KeyBotton_clicked();
|
||||
void on_MF_data2KeyButton_clicked();
|
||||
|
||||
void on_MF_key2DataBotton_clicked();
|
||||
void on_MF_key2DataButton_clicked();
|
||||
|
||||
void on_MF_dataWidget_itemChanged(QTableWidgetItem *item);
|
||||
|
||||
@@ -119,31 +131,95 @@ private slots:
|
||||
|
||||
void on_MF_UID_lockButton_clicked();
|
||||
|
||||
void on_MF_Sim_readSelectedButton_clicked();
|
||||
|
||||
void on_MF_Sim_writeSelectedButton_clicked();
|
||||
|
||||
void on_MF_Sim_clearButton_clicked();
|
||||
|
||||
void on_MF_Sim_simButton_clicked();
|
||||
|
||||
void on_MF_Sniff_loadButton_clicked();
|
||||
|
||||
void on_MF_Sniff_saveButton_clicked();
|
||||
|
||||
void on_GroupBox_clicked(bool checked);
|
||||
|
||||
void on_MF_selectAllBox_stateChanged(int arg1);
|
||||
|
||||
void on_MF_fillKeysButton_clicked();
|
||||
|
||||
void on_MF_14aSniff_snoopButton_clicked();
|
||||
|
||||
void on_MF_trailerDecoderButton_clicked();
|
||||
|
||||
void on_MF_selectTrailerBox_stateChanged(int arg1);
|
||||
|
||||
void on_stopButton_clicked();
|
||||
|
||||
void on_Raw_CMDEdit_textChanged(const QString &arg1);
|
||||
|
||||
void on_MF_Attack_darksideButton_clicked();
|
||||
|
||||
void on_Set_Client_startArgsEdit_editingFinished();
|
||||
|
||||
void on_Set_Client_forceEnabledBox_stateChanged(int arg1);
|
||||
|
||||
void on_Set_GUI_setLanguageButton_clicked();
|
||||
|
||||
void setButtonsEnabled(bool st);
|
||||
|
||||
void on_PM3_refreshPortButton_clicked();
|
||||
|
||||
void on_Set_Client_envScriptEdit_editingFinished();
|
||||
|
||||
void on_Set_Client_saveWorkingDirButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow* ui;
|
||||
QButtonGroup* typeBtnGroup;
|
||||
QButtonGroup* MFCardTypeBtnGroup;
|
||||
QLabel* connectStatusBar;
|
||||
QLabel* programStatusBar;
|
||||
QLabel* PM3VersionBar;
|
||||
QPushButton* stopButton;
|
||||
QAction* myInfo;
|
||||
QAction* currVersion;
|
||||
QAction* checkUpdate;
|
||||
QSettings* settings;
|
||||
MyEventFilter* keyEventFilter;
|
||||
MyEventFilter* resizeEventFilter;
|
||||
|
||||
QString stashedCMDEditText;
|
||||
int stashedIndex = -1;
|
||||
|
||||
void uiInit();
|
||||
|
||||
PM3Process* pm3;
|
||||
bool pm3state;
|
||||
bool keepButtonsEnabled;
|
||||
QThread* pm3Thread;
|
||||
QTimer* portSearchTimer;
|
||||
QStringList portList;
|
||||
QStringList clientEnv;
|
||||
QDir* clientWorkingDir;
|
||||
|
||||
Mifare* mifare;
|
||||
Util* util;
|
||||
|
||||
MF_trailerDecoderDialog* decDialog;
|
||||
|
||||
|
||||
void signalInit();
|
||||
void MF_widgetReset();
|
||||
void setTableItem(QTableWidget *widget, int row, int column, const QString &text);
|
||||
void setTableItem(QTableWidget *widget, int row, int column, const QString& text);
|
||||
void setState(bool st);
|
||||
void saveClientPath(const QString& path);
|
||||
signals:
|
||||
void connectPM3(const QString path, const QString port);
|
||||
void connectPM3(const QString& path, const QString& port, const QStringList args);
|
||||
void reconnectPM3();
|
||||
void killPM3();
|
||||
void setSerialListener(const QString &name, bool state);
|
||||
void setSerialListener(const QString& name, bool state);
|
||||
void setProcEnv(const QStringList *env);
|
||||
void setWorkingDir(const QString& dir);
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
|
||||
@@ -21,6 +21,18 @@ MF_Attack_hardnestedDialog::~MF_Attack_hardnestedDialog()
|
||||
|
||||
void MF_Attack_hardnestedDialog::on_buttonBox_accepted()
|
||||
{
|
||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||
emit sendCMD("hf mf hardnested "
|
||||
+ ui->knownKeySectorBox->currentText()
|
||||
+ " "
|
||||
+ ui->knownKeyTypeBox->currentText()
|
||||
+ " "
|
||||
+ ui->knownKeyBox->text()
|
||||
+ " "
|
||||
+ ui->targetKeySectorBox->currentText()
|
||||
+ " "
|
||||
+ ui->targetKeyTypeBox->currentText());
|
||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
|
||||
emit sendCMD("hf mf hardnested "
|
||||
+ ui->knownKeySectorBox->currentText()
|
||||
+ " "
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#define MF_ATTACK_HARDNESTEDDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace Ui
|
||||
{
|
||||
class MF_Attack_hardnestedDialog;
|
||||
}
|
||||
|
||||
@@ -19,7 +21,7 @@ public:
|
||||
private:
|
||||
Ui::MF_Attack_hardnestedDialog *ui;
|
||||
signals:
|
||||
void sendCMD(QString cmd);
|
||||
void sendCMD(const QString& cmd);
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "mf_sim_simdialog.h"
|
||||
#include "ui_mf_sim_simdialog.h"
|
||||
|
||||
MF_Sim_simDialog::MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::MF_Sim_simDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||
{
|
||||
ui->atqaGroupBox->setVisible(false);
|
||||
ui->atqaLine->setVisible(false);
|
||||
ui->sakGroupBox->setVisible(false);
|
||||
ui->sakLine->setVisible(false);
|
||||
ui->vGroupBox->setVisible(false);
|
||||
ui->vLine->setVisible(false);
|
||||
}
|
||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||
{
|
||||
ui->fGroupBox->setVisible(false);
|
||||
ui->fLine->setVisible(false);
|
||||
ui->rGroupBox->setVisible(false);
|
||||
ui->rLine->setVisible(false);
|
||||
ui->uBox->setText("-u");
|
||||
ui->nBox->setText("-n");
|
||||
ui->iBox->setText("-i");
|
||||
ui->xBox->setText("--crack");
|
||||
ui->eBox->setText("-e");
|
||||
}
|
||||
this->cardType = cardType;
|
||||
this->cardTypeText = cardTypeText;
|
||||
}
|
||||
|
||||
MF_Sim_simDialog::~MF_Sim_simDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MF_Sim_simDialog::on_eBox_clicked(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->iBox->setChecked(true);
|
||||
ui->xBox->setChecked(true);
|
||||
}
|
||||
if(!ui->eBox->isChecked() && !ui->fBox->isChecked())
|
||||
{
|
||||
ui->iBox->setEnabled(true);
|
||||
ui->xBox->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->iBox->setEnabled(false);
|
||||
ui->xBox->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MF_Sim_simDialog::on_fBox_clicked(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
ui->iBox->setChecked(true);
|
||||
ui->xBox->setChecked(true);
|
||||
}
|
||||
if(!ui->eBox->isChecked() && !ui->fBox->isChecked())
|
||||
{
|
||||
ui->iBox->setEnabled(true);
|
||||
ui->xBox->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->iBox->setEnabled(false);
|
||||
ui->xBox->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MF_Sim_simDialog::on_buttonBox_accepted()
|
||||
{
|
||||
QString paras;
|
||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||
{
|
||||
paras += (ui->uBox->isChecked() ? "u " + ui->uEdit->text() + " " : "");
|
||||
paras += (ui->nBox->isChecked() ? "n " + ui->nEdit->text() + " " : "");
|
||||
paras += (ui->iBox->isChecked() ? "i " : "");
|
||||
paras += (ui->xBox->isChecked() ? "x " : "");
|
||||
paras += (ui->eBox->isChecked() ? "e " : "");
|
||||
paras += (ui->fBox->isChecked() ? "f " + ui->fEdit->text() + " " : "");
|
||||
paras += (ui->rBox->isChecked() ? "r " : "");
|
||||
emit sendCMD(QString("hf mf sim ") + "*" + QString::number(cardType) + " " + paras.trimmed());
|
||||
}
|
||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||
{
|
||||
paras += (ui->uBox->isChecked() ? "-u " + ui->uEdit->text() + " " : "");
|
||||
paras += (ui->atqaBox->isChecked() ? "--atqa " + ui->atqaEdit->text() + " " : "");
|
||||
paras += (ui->sakBox->isChecked() ? "--sak " + ui->sakEdit->text() + " " : "");
|
||||
paras += (ui->nBox->isChecked() ? "-n " + ui->nEdit->text() + " " : "");
|
||||
paras += (ui->iBox->isChecked() ? "-i " : "");
|
||||
paras += (ui->xBox->isChecked() ? "--crack " : "");
|
||||
paras += (ui->eBox->isChecked() ? "-e " : "");
|
||||
paras += (ui->vBox->isChecked() ? "-v " : "");
|
||||
emit sendCMD(QString("hf mf sim --") + cardTypeText + " " + paras.trimmed());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef MF_SIM_SIMDIALOG_H
|
||||
#define MF_SIM_SIMDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QDebug>
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MF_Sim_simDialog;
|
||||
}
|
||||
|
||||
class MF_Sim_simDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent = nullptr);
|
||||
~MF_Sim_simDialog();
|
||||
|
||||
private slots:
|
||||
void on_eBox_clicked(bool checked);
|
||||
|
||||
void on_fBox_clicked(bool checked);
|
||||
|
||||
private:
|
||||
Ui::MF_Sim_simDialog *ui;
|
||||
int cardType;
|
||||
QString cardTypeText;
|
||||
signals:
|
||||
void sendCMD(const QString& cmd);
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
};
|
||||
|
||||
#endif // MF_SIM_SIMDIALOG_H
|
||||
@@ -0,0 +1,667 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MF_Sim_simDialog</class>
|
||||
<widget class="QDialog" name="MF_Sim_simDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>461</width>
|
||||
<height>524</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Simulate</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="uGroupBox">
|
||||
<layout class="QHBoxLayout" name="uLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="uBox">
|
||||
<property name="text">
|
||||
<string>u</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="uEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="uLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="atqaGroupBox">
|
||||
<layout class="QHBoxLayout" name="atqaLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="atqaBox">
|
||||
<property name="text">
|
||||
<string>--atqa</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="atqaEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Provide explicit ATQA (2 bytes)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="atqaLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="sakGroupBox">
|
||||
<layout class="QHBoxLayout" name="sakLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="sakBox">
|
||||
<property name="text">
|
||||
<string>--sak</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="sakEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Provide explicit SAK (1 byte)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="sakLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="nGroupBox">
|
||||
<layout class="QHBoxLayout" name="nLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="nBox">
|
||||
<property name="text">
|
||||
<string>n</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="nEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="nLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="iGroupBox">
|
||||
<layout class="QHBoxLayout" name="iLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="iBox">
|
||||
<property name="text">
|
||||
<string>i</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Interactive, means that console will not be returned until simulation finishes or is aborted</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="iLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="xGroupBox">
|
||||
<layout class="QHBoxLayout" name="xLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="xBox">
|
||||
<property name="text">
|
||||
<string>x</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="xLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="eGroupBox">
|
||||
<layout class="QHBoxLayout" name="eLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="eBox">
|
||||
<property name="text">
|
||||
<string>e</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>set keys found from 'reader attack' to emulator memory (implies x(--crack) and i)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="eLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="fGroupBox">
|
||||
<layout class="QHBoxLayout" name="fLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fBox">
|
||||
<property name="text">
|
||||
<string>f</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="fLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="rGroupBox">
|
||||
<layout class="QHBoxLayout" name="rLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="rBox">
|
||||
<property name="text">
|
||||
<string>r</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="rLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="vGroupBox">
|
||||
<layout class="QHBoxLayout" name="vLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="vBox">
|
||||
<property name="text">
|
||||
<string>-v</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>verbose output</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="vLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</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_Sim_simDialog</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_Sim_simDialog</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>
|
||||
@@ -0,0 +1,154 @@
|
||||
#include "mf_trailerdecoderdialog.h"
|
||||
#include "ui_mf_trailerdecoderdialog.h"
|
||||
|
||||
MF_trailerDecoderDialog::MF_trailerDecoderDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::MF_trailerDecoderDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QRegularExpression re("(([0-9a-fA-F]{2} ){0,4})|([0-9a-fA-F]{0,8})");
|
||||
validator = new QRegularExpressionValidator(this);
|
||||
validator->setRegularExpression(re);
|
||||
ui->accessBitsEdit->setValidator(validator);
|
||||
|
||||
sizeGroup = new QButtonGroup(this);
|
||||
sizeGroup->addButton(ui->size4Button, 4);
|
||||
sizeGroup->addButton(ui->size16Button, 16);
|
||||
connect(sizeGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MF_trailerDecoderDialog::on_blockSizeChanged);
|
||||
connect(ui->C0Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||
connect(ui->C1Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||
connect(ui->C2Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||
connect(ui->C3Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||
|
||||
ui->dataBlockWidget->setRowCount(3);
|
||||
ui->dataBlockWidget->setColumnCount(4);
|
||||
ui->trailerBlockWidget->setRowCount(2);
|
||||
ui->trailerBlockWidget->setColumnCount(3);
|
||||
}
|
||||
|
||||
MF_trailerDecoderDialog::~MF_trailerDecoderDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
void MF_trailerDecoderDialog::on_accessBitsEdit_textChanged(const QString &arg1)
|
||||
{
|
||||
ui->C0Box->blockSignals(true);
|
||||
ui->C1Box->blockSignals(true);
|
||||
ui->C2Box->blockSignals(true);
|
||||
ui->C3Box->blockSignals(true);
|
||||
QList<quint8> ACBits = Mifare::data_getACBits(arg1);
|
||||
if(ACBits.size() == 0)
|
||||
{
|
||||
ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(200, 0, 0)");
|
||||
ui->isAccessBitsValidLabel->setText(tr("Invalid!\nIt could make the whole sector blocked irreversibly!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->C0Box->setValue(ACBits[0]);
|
||||
ui->C1Box->setValue(ACBits[1]);
|
||||
ui->C2Box->setValue(ACBits[2]);
|
||||
ui->C3Box->setValue(ACBits[3]);
|
||||
ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(0, 200, 0)");
|
||||
ui->isAccessBitsValidLabel->setText(tr("Valid"));
|
||||
bool isKeyBReadable = ACBits[3] == 0 || ACBits[3] == 1 || ACBits[3] == 4;
|
||||
for(int j = 0; j < 3; j++)
|
||||
{
|
||||
setTableItem(ui->trailerBlockWidget, 0, j, Mifare::trailerReadCondition[ACBits[3]][j]);
|
||||
setTableItem(ui->trailerBlockWidget, 1, j, Mifare::trailerWriteCondition[ACBits[3]][j]);
|
||||
}
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
for(int j = 0; j < 4; j++)
|
||||
{
|
||||
Mifare::AccessType type = Mifare::dataCondition[ACBits[i]][j];
|
||||
if(type == Mifare::ACC_KEY_B && isKeyBReadable)
|
||||
{
|
||||
type = Mifare::ACC_NEVER;
|
||||
}
|
||||
else if(type == Mifare::ACC_KEY_AB && isKeyBReadable)
|
||||
{
|
||||
type = Mifare::ACC_KEY_A;
|
||||
}
|
||||
setTableItem(ui->dataBlockWidget, i, j, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
ui->C0Box->blockSignals(false);
|
||||
ui->C1Box->blockSignals(false);
|
||||
ui->C2Box->blockSignals(false);
|
||||
ui->C3Box->blockSignals(false);
|
||||
}
|
||||
|
||||
void MF_trailerDecoderDialog::on_blockSizeChanged(int id, bool st)
|
||||
{
|
||||
if(st)
|
||||
{
|
||||
if(id == 4)
|
||||
{
|
||||
ui->dataBlockWidget->verticalHeaderItem(0)->setText("Block0");
|
||||
ui->dataBlockWidget->verticalHeaderItem(1)->setText("Block1");
|
||||
ui->dataBlockWidget->verticalHeaderItem(2)->setText("Block2");
|
||||
}
|
||||
else if(id == 16)
|
||||
{
|
||||
ui->dataBlockWidget->verticalHeaderItem(0)->setText("Block0~4");
|
||||
ui->dataBlockWidget->verticalHeaderItem(1)->setText("Block5~9");
|
||||
ui->dataBlockWidget->verticalHeaderItem(2)->setText("Block10~14");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void MF_trailerDecoderDialog::setTableItem(QTableWidget* widget, int row, int column, Mifare::AccessType accessType)
|
||||
{
|
||||
if(widget->item(row, column) == nullptr)
|
||||
widget->setItem(row, column, new QTableWidgetItem());
|
||||
QString text;
|
||||
if(accessType == Mifare::ACC_NEVER)
|
||||
{
|
||||
text = "X";
|
||||
}
|
||||
else if(accessType == Mifare::ACC_KEY_A)
|
||||
{
|
||||
text = "KeyA";
|
||||
}
|
||||
else if(accessType == Mifare::ACC_KEY_B)
|
||||
{
|
||||
text = "KeyB";
|
||||
}
|
||||
else if(accessType == Mifare::ACC_KEY_AB)
|
||||
{
|
||||
text = "KeyA+B";
|
||||
}
|
||||
widget->item(row, column)->setText(text);
|
||||
}
|
||||
|
||||
void MF_trailerDecoderDialog::on_boxChanged()
|
||||
{
|
||||
quint8 ACBits[4];
|
||||
ACBits[0] = ui->C0Box->value();
|
||||
ACBits[1] = ui->C1Box->value();
|
||||
ACBits[2] = ui->C2Box->value();
|
||||
ACBits[3] = ui->C3Box->value();
|
||||
quint8 halfBytes[6] = {0, 0, 0, 0, 0, 0};
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
halfBytes[2] |= (((ACBits[i] >> 0) & 1) << i);
|
||||
halfBytes[5] |= (((ACBits[i] >> 1) & 1) << i);
|
||||
halfBytes[4] |= (((ACBits[i] >> 2) & 1) << i);
|
||||
}
|
||||
halfBytes[0] = (~halfBytes[5]) & 0xf;
|
||||
halfBytes[1] = (~halfBytes[2]) & 0xf;
|
||||
halfBytes[3] = (~halfBytes[4]) & 0xf;
|
||||
|
||||
QString result;
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
result += QString::number(halfBytes[i * 2], 16);
|
||||
result += QString::number(halfBytes[i * 2 + 1], 16);
|
||||
result += " ";
|
||||
}
|
||||
result = result.toUpper();
|
||||
ui->accessBitsEdit->setText(result);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef MF_TRAILERDECODERDIALOG_H
|
||||
#define MF_TRAILERDECODERDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QValidator>
|
||||
#include <QDebug>
|
||||
#include <QButtonGroup>
|
||||
#include <QTableWidget>
|
||||
#include "../module/mifare.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MF_trailerDecoderDialog;
|
||||
}
|
||||
|
||||
class MF_trailerDecoderDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MF_trailerDecoderDialog(QWidget *parent = nullptr);
|
||||
~MF_trailerDecoderDialog();
|
||||
|
||||
private slots:
|
||||
|
||||
void on_accessBitsEdit_textChanged(const QString& arg1);
|
||||
|
||||
void on_blockSizeChanged(int id, bool st);
|
||||
|
||||
void on_boxChanged();
|
||||
private:
|
||||
Ui::MF_trailerDecoderDialog *ui;
|
||||
QRegularExpressionValidator* validator;
|
||||
QButtonGroup* sizeGroup;
|
||||
void setTableItem(QTableWidget *widget, int row, int column, Mifare::AccessType accessType);
|
||||
|
||||
};
|
||||
|
||||
#endif // MF_TRAILERDECODERDIALOG_H
|
||||
@@ -0,0 +1,402 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MF_trailerDecoderDialog</class>
|
||||
<widget class="QDialog" name="MF_trailerDecoderDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>534</width>
|
||||
<height>507</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Trailer Decoder</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="sizeGroupBox">
|
||||
<property name="title">
|
||||
<string>Blocks</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="size4Button">
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="size16Button">
|
||||
<property name="text">
|
||||
<string>16</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Trailer Data:
|
||||
(like "FF0780" or "FF 07 80")</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="accessBitsEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="isAccessBitsValidLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Or set bits manually</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Cx0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="C0Box">
|
||||
<property name="maximum">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Cx1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="C1Box">
|
||||
<property name="maximum">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Cx2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="C2Box">
|
||||
<property name="maximum">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Cx3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="C3Box">
|
||||
<property name="maximum">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Data Block Permission:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="dataBlockWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>4</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Block0</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Block1</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Block2</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Read</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Write</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Increase</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Decrease/Transfer/Restore</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Trailer Block Permission:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="trailerBlockWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>3</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Read</string>
|
||||
</property>
|
||||
</row>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>Write</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>KeyA</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Access Bits</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>KeyB</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Reference:
|
||||
MF1S70YYX_V1 Product data sheet
|
||||
Rev. 3.2 — 23 November 2017</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Note:the Access Bits usually contains 4 bytes(8 hex symbols), but only the first 3 bytes matters. You can set the 4th byte randomly.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>MF_trailerDecoderDialog</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_trailerDecoderDialog</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>
|
||||
@@ -18,6 +18,14 @@ MF_UID_parameterDialog::~MF_UID_parameterDialog()
|
||||
|
||||
void MF_UID_parameterDialog::on_buttonBox_accepted()
|
||||
{
|
||||
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||
emit sendCMD("hf mf csetuid "
|
||||
+ ui->UIDLineEdit->text()
|
||||
+ " "
|
||||
+ ui->ATQALineEdit->text()
|
||||
+ " "
|
||||
+ ui->SAKLineEdit->text());
|
||||
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
|
||||
emit sendCMD("hf mf csetuid "
|
||||
+ ui->UIDLineEdit->text()
|
||||
+ " "
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#define MF_UID_PARAMETERDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Ui {
|
||||
namespace Ui
|
||||
{
|
||||
class MF_UID_parameterDialog;
|
||||
}
|
||||
|
||||
@@ -18,7 +20,7 @@ public:
|
||||
private:
|
||||
Ui::MF_UID_parameterDialog *ui;
|
||||
signals:
|
||||
void sendCMD(QString cmd);
|
||||
void sendCMD(const QString& cmd);
|
||||
private slots:
|
||||
void on_buttonBox_accepted();
|
||||
};
|
||||
|
||||