Compare commits
63 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 |
@@ -14,7 +14,6 @@
|
|||||||
*.so.*
|
*.so.*
|
||||||
*_pch.h.cpp
|
*_pch.h.cpp
|
||||||
*_resource.rc
|
*_resource.rc
|
||||||
*.qm
|
|
||||||
.#*
|
.#*
|
||||||
*.*#
|
*.*#
|
||||||
core
|
core
|
||||||
|
|||||||
@@ -16,25 +16,30 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
common/myeventfilter.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
common/pm3process.cpp \
|
common/pm3process.cpp \
|
||||||
common/util.cpp \
|
common/util.cpp \
|
||||||
module/mifare.cpp \
|
module/mifare.cpp \
|
||||||
|
ui/mf_trailerdecoderdialog.cpp \
|
||||||
ui/mf_sim_simdialog.cpp \
|
ui/mf_sim_simdialog.cpp \
|
||||||
ui/mf_uid_parameterdialog.cpp \
|
ui/mf_uid_parameterdialog.cpp \
|
||||||
ui/mainwindow.cpp \
|
ui/mainwindow.cpp \
|
||||||
ui/mf_attack_hardnesteddialog.cpp \
|
ui/mf_attack_hardnesteddialog.cpp \
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
common/myeventfilter.h \
|
||||||
common/pm3process.h \
|
common/pm3process.h \
|
||||||
common/util.h \
|
common/util.h \
|
||||||
module/mifare.h \
|
module/mifare.h \
|
||||||
|
ui/mf_trailerdecoderdialog.h \
|
||||||
ui/mf_sim_simdialog.h \
|
ui/mf_sim_simdialog.h \
|
||||||
ui/mf_uid_parameterdialog.h \
|
ui/mf_uid_parameterdialog.h \
|
||||||
ui/mainwindow.h \
|
ui/mainwindow.h \
|
||||||
ui/mf_attack_hardnesteddialog.h \
|
ui/mf_attack_hardnesteddialog.h \
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
ui/mf_trailerdecoderdialog.ui \
|
||||||
ui/mf_sim_simdialog.ui \
|
ui/mf_sim_simdialog.ui \
|
||||||
ui/mf_uid_parameterdialog.ui \
|
ui/mf_uid_parameterdialog.ui \
|
||||||
ui/mainwindow.ui \
|
ui/mainwindow.ui \
|
||||||
@@ -49,7 +54,7 @@ qnx: target.path = /tmp/$${TARGET}/bin
|
|||||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
!isEmpty(target.path): INSTALLS += target
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
VERSION = 0.1.1
|
VERSION = 0.1.4
|
||||||
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
||||||
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
||||||
QMAKE_TARGET_COMPANY = "wh201906"
|
QMAKE_TARGET_COMPANY = "wh201906"
|
||||||
|
|||||||
@@ -1,33 +1,93 @@
|
|||||||
# Proxmark3GUI
|
# 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
|
## 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
|
+ Have a friendly UI to test Mifare cards
|
||||||
+ Easy to edit Mifare data files
|
+ Support different card size(MINI, 1K, 2K, 4K)
|
||||||
+ Support binary(.bin .dump) files and text(.eml) files
|
+ 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:
|
## 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
|
### V0.1.1
|
||||||
+ Complete Mifare module(support simulate and sniff)
|
+ Complete Mifare module(support simulate and sniff)
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
# Proxmark3GUI
|
|
||||||
一个自制的[Proxmark3](https://github.com/Proxmark/proxmark3) GUI
|
|
||||||
|
|
||||||
[English](../README.md)
|
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
## 特色功能
|
|
||||||
|
|
||||||
+ 支持直接输入PM3命令
|
|
||||||
+ 有针对于Mifare卡(IC卡)的图形界面
|
|
||||||
+ 支持编辑Mifare扇区数据文件
|
|
||||||
+ 可以打开二进制/文本格式的扇区数据文件
|
|
||||||
+ ...
|
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
## 预览图
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
## 更新日志:
|
|
||||||
|
|
||||||
### V0.1.1
|
|
||||||
+ 完成整个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,31 +14,63 @@ PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent)
|
|||||||
connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead);
|
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);
|
setRequiringOutput(true);
|
||||||
|
|
||||||
|
// stash for reconnect
|
||||||
|
currPath = path;
|
||||||
|
currPort = port;
|
||||||
|
currArgs = args;
|
||||||
|
|
||||||
// using "-f" option to make the client output flushed after every print.
|
// 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))
|
if(waitForStarted(10000))
|
||||||
{
|
{
|
||||||
while(waitForReadyRead(1000))
|
waitForReadyRead(10000);
|
||||||
;
|
|
||||||
setRequiringOutput(false);
|
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
|
if(result.indexOf("os: ") != -1) // make sure the PM3 is connected
|
||||||
{
|
{
|
||||||
|
emit changeClientType(clientType);
|
||||||
result = result.mid(result.indexOf("os: "));
|
result = result.mid(result.indexOf("os: "));
|
||||||
result = result.left(result.indexOf("\r\n"));
|
result = result.left(result.indexOf("\r\n"));
|
||||||
result = result.mid(3, result.lastIndexOf(" ") - 3);
|
result = result.mid(3, result.lastIndexOf(" ") - 3);
|
||||||
emit PM3StatedChanged(true, result);
|
emit PM3StatedChanged(true, result);
|
||||||
setSerialListener(port, true);
|
|
||||||
|
// 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
|
else
|
||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PM3Process::reconnectPM3()
|
||||||
|
{
|
||||||
|
connectPM3(currPath, currPort, currArgs);
|
||||||
|
}
|
||||||
|
|
||||||
void PM3Process::setRequiringOutput(bool st)
|
void PM3Process::setRequiringOutput(bool st)
|
||||||
{
|
{
|
||||||
isRequiringOutput = st;
|
isRequiringOutput = st;
|
||||||
@@ -82,7 +114,6 @@ void PM3Process::testThread()
|
|||||||
qDebug() << "PM3:" << QThread::currentThread();
|
qDebug() << "PM3:" << QThread::currentThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
qint64 PM3Process::write(QString data)
|
qint64 PM3Process::write(QString data)
|
||||||
{
|
{
|
||||||
return QProcess::write(data.toLatin1());
|
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 <QTimer>
|
||||||
#include <QtSerialPort/QSerialPortInfo>
|
#include <QtSerialPort/QSerialPortInfo>
|
||||||
#include <QtSerialPort/QSerialPort>
|
#include <QtSerialPort/QSerialPort>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
class PM3Process : public QProcess
|
class PM3Process : public QProcess
|
||||||
{
|
{
|
||||||
@@ -19,9 +23,12 @@ public:
|
|||||||
void testThread();
|
void testThread();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void connectPM3(const QString path, const QString port);
|
void connectPM3(const QString& path, const QString& port, const QStringList args);
|
||||||
void setSerialListener(const QString &name, bool state);
|
void setSerialListener(const QString& name, bool state);
|
||||||
qint64 write(QString data);
|
qint64 write(QString data);
|
||||||
|
void reconnectPM3();
|
||||||
|
void setProcEnv(const QStringList* env);
|
||||||
|
void setWorkingDir(const QString& dir);
|
||||||
private slots:
|
private slots:
|
||||||
void onTimeout();
|
void onTimeout();
|
||||||
void onReadyRead();
|
void onReadyRead();
|
||||||
@@ -31,9 +38,14 @@ private:
|
|||||||
void setRequiringOutput(bool st);// It only works in this class now
|
void setRequiringOutput(bool st);// It only works in this class now
|
||||||
QTimer* serialListener;
|
QTimer* serialListener;
|
||||||
QSerialPortInfo* portInfo;
|
QSerialPortInfo* portInfo;
|
||||||
|
QString currPath;
|
||||||
|
QString currPort;
|
||||||
|
QStringList currArgs;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void PM3StatedChanged(bool st, QString info = "");
|
void PM3StatedChanged(bool st, const QString& info = "");
|
||||||
void newOutput(QString output);
|
void newOutput(const QString& output);
|
||||||
|
void changeClientType(Util::ClientType);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PM3PROCESS_H
|
#endif // PM3PROCESS_H
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
Util::ClientType Util::clientType = CLIENTTYPE_OFFICIAL;
|
||||||
|
|
||||||
Util::Util(QObject *parent) : QObject(parent)
|
Util::Util(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
isRequiringOutput = false;
|
isRequiringOutput = false;
|
||||||
requiredOutput = new QString();
|
requiredOutput = new QString();
|
||||||
timeStamp = QTime::currentTime();
|
timeStamp = QTime::currentTime();
|
||||||
|
qRegisterMetaType<Util::ClientType>("Util::ClientType");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Util::processOutput(QString output)
|
void Util::processOutput(const QString& output)
|
||||||
{
|
{
|
||||||
// qDebug() << "Util::processOutput:" << output;
|
// qDebug() << "Util::processOutput:" << output;
|
||||||
if(isRequiringOutput)
|
if(isRequiringOutput)
|
||||||
@@ -18,35 +21,102 @@ void Util::processOutput(QString output)
|
|||||||
emit refreshOutput(output);
|
emit refreshOutput(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Util::execCMD(QString cmd)
|
void Util::execCMD(const QString& cmd)
|
||||||
{
|
{
|
||||||
qDebug() << cmd;
|
qDebug() << "executing: " << cmd;
|
||||||
emit write(cmd + "\r\n");
|
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 currTime = QTime::currentTime();
|
||||||
QTime targetTime = QTime::currentTime().addMSecs(timeout);
|
QTime targetTime = QTime::currentTime().addMSecs(trigger.waitTime);
|
||||||
isRequiringOutput = true;
|
isRequiringOutput = true;
|
||||||
requiredOutput->clear();
|
requiredOutput->clear();
|
||||||
execCMD(cmd);
|
execCMD(cmd);
|
||||||
while( QTime::currentTime() < targetTime)
|
while(QTime::currentTime() < targetTime)
|
||||||
{
|
{
|
||||||
|
if(!isRunning)
|
||||||
|
break;
|
||||||
QApplication::processEvents();
|
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;
|
currTime = timeStamp;
|
||||||
targetTime = timeStamp.addMSecs(timeout);
|
targetTime = timeStamp.addMSecs(trigger.waitTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isRequiringOutput = false;
|
isRequiringOutput = false;
|
||||||
return *requiredOutput;
|
return (isResultFound || trigger.expectedOutputs.isEmpty() ? *requiredOutput : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Util::delay(unsigned int msec)
|
void Util::delay(unsigned int msec)
|
||||||
{
|
{
|
||||||
QTime timer = QTime::currentTime().addMSecs(msec);
|
QTime timer = QTime::currentTime().addMSecs(msec);
|
||||||
while( QTime::currentTime() < timer )
|
while(QTime::currentTime() < timer)
|
||||||
QApplication::processEvents(QEventLoop::AllEvents, 100);
|
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 <QApplication>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
class Util : public QObject
|
class Util : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
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);
|
explicit Util(QObject *parent = nullptr);
|
||||||
|
|
||||||
void execCMD(QString cmd);
|
void execCMD(const QString& cmd);
|
||||||
QString execCMDWithOutput(QString cmd, unsigned long timeout = 2000);
|
QString execCMDWithOutput(const QString& cmd, ReturnTrigger trigger = 10000);
|
||||||
void delay(unsigned int msec);
|
void delay(unsigned int msec);
|
||||||
|
static ClientType getClientType();
|
||||||
|
static const int rawTabIndex = 1;
|
||||||
|
static bool chooseLanguage(QSettings *guiSettings, QMainWindow *window);
|
||||||
public slots:
|
public slots:
|
||||||
void processOutput(QString output);
|
void processOutput(const QString& output);
|
||||||
|
static void setClientType(Util::ClientType clientType);
|
||||||
|
void setRunningState(bool st);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isRequiringOutput;
|
bool isRequiringOutput;
|
||||||
|
bool isRunning;
|
||||||
QString* requiredOutput;
|
QString* requiredOutput;
|
||||||
QTime timeStamp;
|
QTime timeStamp;
|
||||||
|
static ClientType clientType;
|
||||||
signals:
|
signals:
|
||||||
void refreshOutput(const QString& output);
|
void refreshOutput(const QString& output);
|
||||||
void write(QString data);
|
void write(QString data); // connected to PM3Process::write(QString data);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UTIL_H
|
#endif // UTIL_H
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[Languages]
|
||||||
|
en_US=English
|
||||||
|
zh_CN=简体中文
|
||||||
@@ -4,54 +4,50 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QInputDialog>
|
#include <QTextCodec>
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
|
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
|
|
||||||
QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
|
QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
|
||||||
QVariant lang = settings->value("lang", "null");
|
settings->setIniCodec("UTF-8");
|
||||||
if(lang == "null")
|
settings->beginGroup("lang");
|
||||||
|
QString currLang = settings->value("language", "").toString();
|
||||||
|
settings->endGroup();
|
||||||
|
if(currLang == "")
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
if(Util::chooseLanguage(settings, &w))
|
||||||
lang = "lang/en_US.qm";
|
|
||||||
#else
|
|
||||||
lang = "lang/en_US.ts";
|
|
||||||
#endif
|
|
||||||
QStringList langList;
|
|
||||||
langList.append("English");
|
|
||||||
langList.append("简体中文");
|
|
||||||
QString seletedText = QInputDialog::getItem(&w, "", "Choose a language:", langList, 0, false);
|
|
||||||
if(seletedText == "English")
|
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
settings->beginGroup("lang");
|
||||||
lang = "lang/en_US.qm";
|
currLang = settings->value("language", "").toString();
|
||||||
#else
|
settings->endGroup();
|
||||||
lang = "lang/en_US.ts";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if(seletedText == "简体中文")
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
lang = "lang/zh_CN.qm";
|
|
||||||
#else
|
|
||||||
lang = "lang/zh_CN.ts";
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
currLang = "en_US";
|
||||||
}
|
}
|
||||||
|
currLang = "lang/" + currLang;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
currLang += ".qm";
|
||||||
|
#else
|
||||||
|
currLang += ".ts";;
|
||||||
|
#endif
|
||||||
QTranslator* translator = new QTranslator(&w);
|
QTranslator* translator = new QTranslator(&w);
|
||||||
if(translator->load(lang.toString()))
|
if(translator->load(currLang))
|
||||||
{
|
{
|
||||||
a.installTranslator(translator);
|
a.installTranslator(translator);
|
||||||
settings->setValue("lang", lang);
|
|
||||||
}
|
}
|
||||||
else
|
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;
|
delete settings;
|
||||||
w.initUI();
|
w.initUI();
|
||||||
w.show();
|
w.show();
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QRegExp>
|
#include <QRegularExpression>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
class Mifare : public QObject
|
class Mifare : public QObject
|
||||||
{
|
{
|
||||||
@@ -17,18 +17,11 @@ class Mifare : public QObject
|
|||||||
public:
|
public:
|
||||||
explicit Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr);
|
explicit Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr);
|
||||||
|
|
||||||
QString info(bool isRequiringOutput = false);
|
enum KeyType
|
||||||
void chk();
|
{
|
||||||
void nested();
|
KEY_A = 'A',
|
||||||
void hardnested();
|
KEY_B = 'B',
|
||||||
void sniff();
|
};
|
||||||
void list();
|
|
||||||
void read();
|
|
||||||
void readAll();
|
|
||||||
void write();
|
|
||||||
void writeAll();
|
|
||||||
void dump();
|
|
||||||
void restore();
|
|
||||||
|
|
||||||
enum DataType
|
enum DataType
|
||||||
{
|
{
|
||||||
@@ -39,79 +32,85 @@ public:
|
|||||||
|
|
||||||
struct CardType
|
struct CardType
|
||||||
{
|
{
|
||||||
int type;
|
quint8 type;
|
||||||
int sectors;
|
quint8 sector_size;
|
||||||
int blocks;
|
quint16 block_size;
|
||||||
int blk[40];
|
quint8 blk[40];
|
||||||
int blks[40];
|
quint8 blks[40];
|
||||||
|
QString typeText;
|
||||||
};
|
};
|
||||||
|
|
||||||
const CardType card_mini =
|
enum AccessType
|
||||||
{
|
{
|
||||||
0,
|
ACC_NEVER = 0,
|
||||||
5,
|
ACC_KEY_A = 1,
|
||||||
20,
|
ACC_KEY_B = 2,
|
||||||
{4, 4, 4, 4, 4},
|
ACC_KEY_AB = 3,
|
||||||
{0, 4, 8, 12, 16}
|
|
||||||
};
|
|
||||||
const CardType card_1k =
|
|
||||||
{
|
|
||||||
1,
|
|
||||||
16,
|
|
||||||
64,
|
|
||||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
|
||||||
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60}
|
|
||||||
};
|
|
||||||
const CardType card_2k =
|
|
||||||
{
|
|
||||||
2,
|
|
||||||
32,
|
|
||||||
128,
|
|
||||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
|
|
||||||
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124}
|
|
||||||
};
|
|
||||||
const CardType card_4k =
|
|
||||||
{
|
|
||||||
4,
|
|
||||||
40,
|
|
||||||
256,
|
|
||||||
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 16},
|
|
||||||
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 144, 160, 176, 192, 208, 224, 240}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void data_clearData();
|
enum TargetType
|
||||||
void data_clearKey();
|
{
|
||||||
bool data_isKeyValid(const QString &key);
|
TARGET_MIFARE,
|
||||||
Mifare::DataType data_isDataValid(QString data);
|
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_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;
|
CardType cardType;
|
||||||
Mifare::CardType getCardType();
|
Mifare::CardType getCardType();
|
||||||
void setCardType(int type);
|
void setCardType(int type);
|
||||||
void writeAllC();
|
|
||||||
void writeC();
|
|
||||||
void readAllC();
|
|
||||||
void readC();
|
|
||||||
void wipeC();
|
void wipeC();
|
||||||
void setParameterC();
|
void setParameterC();
|
||||||
|
|
||||||
bool data_loadDataFile(const QString &filename);
|
bool data_loadDataFile(const QString& filename);
|
||||||
bool data_loadKeyFile(const QString &filename);
|
bool data_loadKeyFile(const QString& filename);
|
||||||
bool data_saveDataFile(const QString& filename, bool isBin);
|
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_key2Data();
|
||||||
void data_data2Key();
|
void data_data2Key();
|
||||||
|
|
||||||
void data_setData(int block, const QString &data);
|
void data_setData(int block, const QString& data);
|
||||||
void data_setKey(int sector, bool isKeyA, const QString &key);
|
void data_setKey(int sector, KeyType keyType, const QString& key);
|
||||||
void lockC();
|
void lockC();
|
||||||
void writeAllE();
|
|
||||||
void readAllE();
|
|
||||||
void wipeE();
|
void wipeE();
|
||||||
void simulate();
|
void simulate();
|
||||||
void loadSniff(const QString& file);
|
void loadSniff(const QString& file);
|
||||||
void saveSniff(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:
|
public slots:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
@@ -123,11 +122,14 @@ private:
|
|||||||
QStringList* keyAList;
|
QStringList* keyAList;
|
||||||
QStringList* keyBList;
|
QStringList* keyBList;
|
||||||
QStringList* dataList;
|
QStringList* dataList;
|
||||||
QRegExp* dataPattern;
|
QRegularExpression* dataPattern;
|
||||||
QRegExp* chkKeyPattern;
|
QRegularExpression* keyPattern_res;
|
||||||
QRegExp* nestedKeyPattern;
|
QRegularExpression* keyPattern;
|
||||||
QRegExp* UIDPattern;
|
QString bin2text(const QByteArray& buff, int start, int length);
|
||||||
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
|
#endif // MIFARE_H
|
||||||
|
|||||||
@@ -6,25 +6,45 @@ MainWindow::MainWindow(QWidget *parent):
|
|||||||
, ui(new Ui::MainWindow)
|
, ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
// ui->MF_simGroupBox->setVisible(false); // developing...
|
|
||||||
// ui->MF_sniffGroupBox->setVisible(false); // developing...
|
|
||||||
myInfo = new QAction("wh201906", this);
|
myInfo = new QAction("wh201906", this);
|
||||||
|
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, [ = ]()
|
connect(myInfo, &QAction::triggered, [ = ]()
|
||||||
{
|
{
|
||||||
QDesktopServices::openUrl(QUrl("https://github.com/wh201906"));
|
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(myInfo);
|
||||||
|
this->addAction(currVersion);
|
||||||
|
this->addAction(checkUpdate);
|
||||||
|
|
||||||
|
settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
|
||||||
|
settings->setIniCodec("UTF-8");
|
||||||
|
|
||||||
pm3Thread = new QThread(this);
|
pm3Thread = new QThread(this);
|
||||||
pm3 = new PM3Process(pm3Thread);
|
pm3 = new PM3Process(pm3Thread);
|
||||||
// pm3->moveToThread(pm3Thread);
|
|
||||||
// pm3->init();
|
|
||||||
pm3Thread->start();
|
pm3Thread->start();
|
||||||
pm3state = false;
|
pm3state = false;
|
||||||
|
clientWorkingDir = new QDir;
|
||||||
|
|
||||||
util = new Util(this);
|
util = new Util(this);
|
||||||
mifare = new Mifare(ui, 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()
|
MainWindow::~MainWindow()
|
||||||
@@ -47,62 +67,89 @@ void MainWindow::initUI() // will be called by main.app
|
|||||||
|
|
||||||
// ******************** basic functions ********************
|
// ******************** basic functions ********************
|
||||||
|
|
||||||
void MainWindow::on_PM3_refreshPortButton_clicked()
|
void MainWindow::on_portSearchTimer_timeout()
|
||||||
{
|
{
|
||||||
ui->PM3_portBox->clear();
|
QStringList newPortList;
|
||||||
QSerialPort serial;
|
|
||||||
QStringList serialList;
|
|
||||||
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
||||||
{
|
{
|
||||||
qDebug() << info.isBusy() << info.isNull() << info.portName();
|
// qDebug() << info.isBusy() << info.isNull() << info.portName() << info.description();
|
||||||
serial.setPort(info);
|
if(!info.isNull())
|
||||||
|
newPortList << info.portName();
|
||||||
if(serial.open(QIODevice::ReadWrite))
|
|
||||||
{
|
|
||||||
serialList << info.portName();
|
|
||||||
serial.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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()
|
void MainWindow::on_PM3_connectButton_clicked()
|
||||||
{
|
{
|
||||||
qDebug() << "Main:" << QThread::currentThread();
|
qDebug() << "Main:" << QThread::currentThread();
|
||||||
|
|
||||||
QString port = ui->PM3_portBox->currentText();
|
QString port = ui->PM3_portBox->currentText();
|
||||||
if(port == "")
|
if(port == "")
|
||||||
QMessageBox::information(NULL, tr("Info"), tr("Plz choose a port first"), QMessageBox::Ok);
|
QMessageBox::information(NULL, tr("Info"), tr("Plz choose a port first"), QMessageBox::Ok);
|
||||||
else
|
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;
|
pm3state = st;
|
||||||
setState(st);
|
setState(st);
|
||||||
if(st == true)
|
if(st == true)
|
||||||
{
|
{
|
||||||
|
portSearchTimer->stop();
|
||||||
setStatusBar(PM3VersionBar, info);
|
setStatusBar(PM3VersionBar, info);
|
||||||
setStatusBar(connectStatusBar, tr("Connected"));
|
setStatusBar(connectStatusBar, tr("Connected"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
portSearchTimer->start();
|
||||||
|
setStatusBar(PM3VersionBar, "");
|
||||||
setStatusBar(connectStatusBar, tr("Not Connected"));
|
setStatusBar(connectStatusBar, tr("Not Connected"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_PM3_disconnectButton_clicked()
|
void MainWindow::on_PM3_disconnectButton_clicked()
|
||||||
{
|
{
|
||||||
pm3state = false;
|
|
||||||
setState(false);
|
|
||||||
emit killPM3();
|
emit killPM3();
|
||||||
emit setSerialListener("", false);
|
emit setSerialListener("", false);
|
||||||
setStatusBar(connectStatusBar, tr("Not Connected"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshOutput(const QString& output)
|
void MainWindow::refreshOutput(const QString& output)
|
||||||
@@ -112,17 +159,31 @@ void MainWindow::refreshOutput(const QString& output)
|
|||||||
ui->Raw_outputEdit->moveCursor(QTextCursor::End);
|
ui->Raw_outputEdit->moveCursor(QTextCursor::End);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::refreshCMD(const QString& cmd)
|
void MainWindow::on_stopButton_clicked()
|
||||||
{
|
{
|
||||||
ui->Raw_CMDEdit->setText(cmd);
|
if(!pm3state)
|
||||||
if(cmd != "" && (ui->Raw_CMDHistoryWidget->count() == 0 || ui->Raw_CMDHistoryWidget->item(ui->Raw_CMDHistoryWidget->count() - 1)->text() != cmd))
|
on_PM3_disconnectButton_clicked();
|
||||||
ui->Raw_CMDHistoryWidget->addItem(cmd);
|
else
|
||||||
|
{
|
||||||
|
on_PM3_disconnectButton_clicked();
|
||||||
|
for(int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
util->delay(200);
|
||||||
|
if(!pm3state)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
emit reconnectPM3();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// *********************************************************
|
// *********************************************************
|
||||||
|
|
||||||
// ******************** raw command ********************
|
// ******************** raw command ********************
|
||||||
|
|
||||||
|
void MainWindow::on_Raw_CMDEdit_textChanged(const QString &arg1)
|
||||||
|
{
|
||||||
|
stashedCMDEditText = arg1;
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_Raw_sendCMDButton_clicked()
|
void MainWindow::on_Raw_sendCMDButton_clicked()
|
||||||
{
|
{
|
||||||
util->execCMD(ui->Raw_CMDEdit->text());
|
util->execCMD(ui->Raw_CMDEdit->text());
|
||||||
@@ -167,41 +228,184 @@ void MainWindow::sendMSG() // send command when pressing Enter
|
|||||||
on_Raw_sendCMDButton_clicked();
|
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 ********************
|
// ******************** mifare ********************
|
||||||
void MainWindow::MF_onTypeChanged(int id, bool st)
|
void MainWindow::on_MF_keyWidget_resized(QObject* obj_addr, QEvent& event)
|
||||||
{
|
{
|
||||||
typeBtnGroup->blockSignals(true);
|
if(obj_addr == ui->MF_keyWidget && event.type() == QEvent::Resize)
|
||||||
qDebug() << id << typeBtnGroup->checkedId();
|
{
|
||||||
|
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)
|
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)
|
if(result == QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
qDebug() << "Yes";
|
qDebug() << "Yes";
|
||||||
mifare->setCardType(typeBtnGroup->checkedId());
|
mifare->setCardType(MFCardTypeBtnGroup->checkedId());
|
||||||
MF_widgetReset();
|
MF_widgetReset();
|
||||||
|
mifare->data_syncWithDataWidget();
|
||||||
|
mifare->data_syncWithKeyWidget();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug() << "No";
|
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();
|
mifare->data_data2Key();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_key2DataBotton_clicked()
|
void MainWindow::on_MF_key2DataButton_clicked()
|
||||||
{
|
{
|
||||||
mifare->data_key2Data();
|
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()
|
void MainWindow::on_MF_fontButton_clicked()
|
||||||
{
|
{
|
||||||
bool isOK = false;
|
bool isOK = false;
|
||||||
@@ -216,8 +420,100 @@ void MainWindow::on_MF_fontButton_clicked()
|
|||||||
|
|
||||||
void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
|
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();
|
QString data = item->text().replace(" ", "").toUpper();
|
||||||
if(data == "" || mifare->data_isDataValid(data) == Mifare::DATA_NOSPACE)
|
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());
|
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)
|
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();
|
QString key = item->text().replace(" ", "").toUpper();
|
||||||
if(key == "" || mifare->data_isKeyValid(key))
|
if(key == "" || mifare->data_isKeyValid(key))
|
||||||
{
|
{
|
||||||
mifare->data_setKey(item->row(), true, key);
|
mifare->data_setKey(item->row(), Mifare::KEY_A, key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)"));
|
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)
|
else if(item->column() == 2)
|
||||||
{
|
{
|
||||||
QString key = item->text().replace(" ", "");
|
QString key = item->text().replace(" ", "").toUpper();
|
||||||
if(key == "" || mifare->data_isKeyValid(key))
|
if(key == "" || mifare->data_isKeyValid(key))
|
||||||
{
|
{
|
||||||
mifare->data_setKey(item->row(), false, key);
|
mifare->data_setKey(item->row(), Mifare::KEY_B, key);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)"));
|
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();
|
mifare->hardnested();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_RW_readAllButton_clicked()
|
void MainWindow::on_MF_RW_readSelectedButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->readAll();
|
mifare->readSelected(Mifare::TARGET_MIFARE);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_RW_readBlockButton_clicked()
|
void MainWindow::on_MF_RW_readBlockButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->read();
|
mifare->readOne(Mifare::TARGET_MIFARE);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_RW_writeBlockButton_clicked()
|
void MainWindow::on_MF_RW_writeBlockButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->write();
|
mifare->writeOne();
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_RW_writeAllButton_clicked()
|
void MainWindow::on_MF_RW_writeSelectedButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->writeAll();
|
mifare->writeSelected(Mifare::TARGET_MIFARE);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,31 +706,31 @@ void MainWindow::on_MF_RW_restoreButton_clicked()
|
|||||||
mifare->restore();
|
mifare->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_UID_readAllButton_clicked()
|
void MainWindow::on_MF_UID_readSelectedButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->readAllC();
|
mifare->readSelected(Mifare::TARGET_UID);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_UID_readBlockButton_clicked()
|
void MainWindow::on_MF_UID_readBlockButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->readC();
|
mifare->readOne(Mifare::TARGET_UID);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_UID_writeAllButton_clicked()
|
void MainWindow::on_MF_UID_writeSelectedButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->writeAllC();
|
mifare->writeSelected(Mifare::TARGET_UID);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_UID_writeBlockButton_clicked()
|
void MainWindow::on_MF_UID_writeBlockButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->writeC();
|
mifare->writeOne(Mifare::TARGET_UID);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,17 +772,17 @@ void MainWindow::on_MF_UID_lockButton_clicked()
|
|||||||
mifare->lockC();
|
mifare->lockC();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_Sim_loadDataButton_clicked()
|
void MainWindow::on_MF_Sim_readSelectedButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->writeAllE();
|
mifare->readSelected(Mifare::TARGET_EMULATOR);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_Sim_writeAllButton_clicked()
|
void MainWindow::on_MF_Sim_writeSelectedButton_clicked()
|
||||||
{
|
{
|
||||||
setState(false);
|
setState(false);
|
||||||
mifare->readAllE();
|
mifare->writeSelected(Mifare::TARGET_EMULATOR);
|
||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,6 +847,13 @@ void MainWindow::on_MF_Sniff_sniffButton_clicked()
|
|||||||
setState(true);
|
setState(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_MF_14aSniff_snoopButton_clicked()
|
||||||
|
{
|
||||||
|
setState(false);
|
||||||
|
mifare->sniff14a();
|
||||||
|
setState(true);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_MF_Sniff_listButton_clicked()
|
void MainWindow::on_MF_Sniff_listButton_clicked()
|
||||||
{
|
{
|
||||||
mifare->list();
|
mifare->list();
|
||||||
@@ -555,16 +861,23 @@ void MainWindow::on_MF_Sniff_listButton_clicked()
|
|||||||
|
|
||||||
void MainWindow::MF_widgetReset()
|
void MainWindow::MF_widgetReset()
|
||||||
{
|
{
|
||||||
int secs = mifare->cardType.sectors;
|
int secs = mifare->cardType.sector_size;
|
||||||
int blks = mifare->cardType.blocks;
|
int blks = mifare->cardType.block_size;
|
||||||
|
QBrush trailerItemForeColor = QBrush(QColor(0, 160, 255));
|
||||||
ui->MF_RW_blockBox->clear();
|
ui->MF_RW_blockBox->clear();
|
||||||
ui->MF_keyWidget->setRowCount(secs);
|
ui->MF_keyWidget->setRowCount(secs);
|
||||||
ui->MF_dataWidget->setRowCount(blks);
|
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++)
|
for(int i = 0; i < blks; i++)
|
||||||
{
|
{
|
||||||
setTableItem(ui->MF_dataWidget, i, 0, "");
|
setTableItem(ui->MF_dataWidget, i, 0, "");
|
||||||
setTableItem(ui->MF_dataWidget, i, 1, QString::number(i));
|
setTableItem(ui->MF_dataWidget, i, 1, QString::number(i));
|
||||||
|
ui->MF_dataWidget->item(i, 1)->setCheckState(Qt::Checked);
|
||||||
setTableItem(ui->MF_dataWidget, i, 2, "");
|
setTableItem(ui->MF_dataWidget, i, 2, "");
|
||||||
ui->MF_RW_blockBox->addItem(QString::number(i));
|
ui->MF_RW_blockBox->addItem(QString::number(i));
|
||||||
}
|
}
|
||||||
@@ -575,7 +888,17 @@ void MainWindow::MF_widgetReset()
|
|||||||
setTableItem(ui->MF_keyWidget, i, 1, "");
|
setTableItem(ui->MF_keyWidget, i, 1, "");
|
||||||
setTableItem(ui->MF_keyWidget, i, 2, "");
|
setTableItem(ui->MF_keyWidget, i, 2, "");
|
||||||
setTableItem(ui->MF_dataWidget, mifare->cardType.blks[i], 0, QString::number(i));
|
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);
|
||||||
}
|
}
|
||||||
// ************************************************
|
// ************************************************
|
||||||
|
|
||||||
@@ -585,63 +908,122 @@ void MainWindow::MF_widgetReset()
|
|||||||
void MainWindow::uiInit()
|
void MainWindow::uiInit()
|
||||||
{
|
{
|
||||||
connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG);
|
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);
|
connectStatusBar = new QLabel(this);
|
||||||
programStatusBar = new QLabel(this);
|
programStatusBar = new QLabel(this);
|
||||||
PM3VersionBar = new QLabel(this);
|
PM3VersionBar = new QLabel(this);
|
||||||
|
stopButton = new QPushButton(this);
|
||||||
setStatusBar(connectStatusBar, tr("Not Connected"));
|
setStatusBar(connectStatusBar, tr("Not Connected"));
|
||||||
setStatusBar(programStatusBar, tr("Idle"));
|
setStatusBar(programStatusBar, tr("Idle"));
|
||||||
setStatusBar(PM3VersionBar, "");
|
setStatusBar(PM3VersionBar, "");
|
||||||
|
stopButton->setText(tr("Stop"));
|
||||||
ui->statusbar->addPermanentWidget(PM3VersionBar, 1);
|
ui->statusbar->addPermanentWidget(PM3VersionBar, 1);
|
||||||
ui->statusbar->addPermanentWidget(connectStatusBar, 1);
|
ui->statusbar->addPermanentWidget(connectStatusBar, 1);
|
||||||
ui->statusbar->addPermanentWidget(programStatusBar, 1);
|
ui->statusbar->addPermanentWidget(programStatusBar, 1);
|
||||||
|
ui->statusbar->addPermanentWidget(stopButton);
|
||||||
|
|
||||||
ui->MF_dataWidget->setColumnCount(3);
|
ui->MF_dataWidget->setColumnCount(3);
|
||||||
ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
|
ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
|
||||||
ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Blk")));
|
ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Blk")));
|
||||||
ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Data")));
|
ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Data")));
|
||||||
ui->MF_dataWidget->verticalHeader()->setVisible(false);
|
ui->MF_dataWidget->setColumnWidth(0, 55);
|
||||||
ui->MF_dataWidget->setColumnWidth(0, 35);
|
ui->MF_dataWidget->setColumnWidth(1, 55);
|
||||||
ui->MF_dataWidget->setColumnWidth(1, 35);
|
|
||||||
ui->MF_dataWidget->setColumnWidth(2, 430);
|
|
||||||
|
|
||||||
ui->MF_keyWidget->setColumnCount(3);
|
ui->MF_keyWidget->setColumnCount(3);
|
||||||
ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
|
ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
|
||||||
ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("KeyA")));
|
ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("KeyA")));
|
||||||
ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB")));
|
ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB")));
|
||||||
ui->MF_keyWidget->verticalHeader()->setVisible(false);
|
ui->MF_keyWidget->setColumnWidth(0, 45);
|
||||||
ui->MF_keyWidget->setColumnWidth(0, 35);
|
|
||||||
ui->MF_keyWidget->setColumnWidth(1, 115);
|
|
||||||
ui->MF_keyWidget->setColumnWidth(2, 115);
|
|
||||||
|
|
||||||
MF_widgetReset();
|
MF_widgetReset();
|
||||||
typeBtnGroup = new QButtonGroup(this);
|
MFCardTypeBtnGroup = new QButtonGroup(this);
|
||||||
typeBtnGroup->addButton(ui->MF_Type_miniButton, 0);
|
MFCardTypeBtnGroup->addButton(ui->MF_Type_miniButton, 0);
|
||||||
typeBtnGroup->addButton(ui->MF_Type_1kButton, 1);
|
MFCardTypeBtnGroup->addButton(ui->MF_Type_1kButton, 1);
|
||||||
typeBtnGroup->addButton(ui->MF_Type_2kButton, 2);
|
MFCardTypeBtnGroup->addButton(ui->MF_Type_2kButton, 2);
|
||||||
typeBtnGroup->addButton(ui->MF_Type_4kButton, 4);
|
MFCardTypeBtnGroup->addButton(ui->MF_Type_4kButton, 4);
|
||||||
connect(typeBtnGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MainWindow::MF_onTypeChanged);
|
connect(MFCardTypeBtnGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MainWindow::MF_onMFCardTypeChanged);
|
||||||
|
|
||||||
ui->MF_keyWidget->installEventFilter(this);
|
ui->MF_keyWidget->installEventFilter(this);
|
||||||
ui->MF_dataWidget->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_Raw_CMDHistoryBox_stateChanged(Qt::Unchecked);
|
||||||
on_PM3_refreshPortButton_clicked();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::signalInit()
|
void MainWindow::signalInit()
|
||||||
{
|
{
|
||||||
connect(pm3, &PM3Process::newOutput, util, &Util::processOutput);
|
connect(pm3, &PM3Process::newOutput, util, &Util::processOutput);
|
||||||
|
connect(pm3, &PM3Process::changeClientType, util, &Util::setClientType);
|
||||||
connect(util, &Util::refreshOutput, this, &MainWindow::refreshOutput);
|
connect(util, &Util::refreshOutput, this, &MainWindow::refreshOutput);
|
||||||
|
|
||||||
connect(this, &MainWindow::connectPM3, pm3, &PM3Process::connectPM3);
|
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, this, &MainWindow::onPM3StateChanged);
|
||||||
|
connect(pm3, &PM3Process::PM3StatedChanged, util, &Util::setRunningState);
|
||||||
connect(this, &MainWindow::killPM3, pm3, &PM3Process::kill);
|
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(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)
|
if(target == PM3VersionBar)
|
||||||
target->setText(tr("HW Version:") + text);
|
target->setText(tr("HW Version:") + text);
|
||||||
@@ -651,14 +1033,14 @@ void MainWindow::setStatusBar(QLabel* target, const QString & text)
|
|||||||
target->setText(tr("State:") + 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)
|
if(widget->item(row, column) == nullptr)
|
||||||
widget->setItem(row, column, new QTableWidgetItem());
|
widget->setItem(row, column, new QTableWidgetItem());
|
||||||
widget->item(row, column)->setText(text);
|
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)
|
if(event->type() == QEvent::DragEnter)
|
||||||
{
|
{
|
||||||
@@ -709,6 +1091,11 @@ void MainWindow::setState(bool st)
|
|||||||
{
|
{
|
||||||
setStatusBar(programStatusBar, tr("Idle"));
|
setStatusBar(programStatusBar, tr("Idle"));
|
||||||
}
|
}
|
||||||
|
setButtonsEnabled(st || keepButtonsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setButtonsEnabled(bool st)
|
||||||
|
{
|
||||||
ui->MF_attackGroupBox->setEnabled(st);
|
ui->MF_attackGroupBox->setEnabled(st);
|
||||||
ui->MF_normalGroupBox->setEnabled(st);
|
ui->MF_normalGroupBox->setEnabled(st);
|
||||||
ui->MF_UIDGroupBox->setEnabled(st);
|
ui->MF_UIDGroupBox->setEnabled(st);
|
||||||
@@ -718,8 +1105,78 @@ void MainWindow::setState(bool st)
|
|||||||
ui->Raw_sendCMDButton->setEnabled(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,10 +16,19 @@
|
|||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QDesktopServices>
|
#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 "common/pm3process.h"
|
||||||
#include "module/mifare.h"
|
#include "module/mifare.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
#include "ui/mf_trailerdecoderdialog.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui
|
namespace Ui
|
||||||
@@ -39,11 +48,13 @@ public:
|
|||||||
void initUI();
|
void initUI();
|
||||||
bool eventFilter(QObject *watched, QEvent *event);
|
bool eventFilter(QObject *watched, QEvent *event);
|
||||||
public slots:
|
public slots:
|
||||||
void refreshOutput(const QString &output);
|
void refreshOutput(const QString& output);
|
||||||
void refreshCMD(const QString &cmd);
|
void refreshCMD(const QString& cmd);
|
||||||
void setStatusBar(QLabel* target, const QString & text);
|
void setStatusBar(QLabel* target, const QString& text);
|
||||||
void onPM3StateChanged(bool st, QString info);
|
void onPM3StateChanged(bool st, const QString& info);
|
||||||
void MF_onTypeChanged(int id, bool st);
|
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:
|
private slots:
|
||||||
|
|
||||||
void on_PM3_connectButton_clicked();
|
void on_PM3_connectButton_clicked();
|
||||||
@@ -55,7 +66,8 @@ private slots:
|
|||||||
void on_Raw_clearOutputButton_clicked();
|
void on_Raw_clearOutputButton_clicked();
|
||||||
|
|
||||||
void sendMSG();
|
void sendMSG();
|
||||||
void on_PM3_refreshPortButton_clicked();
|
|
||||||
|
void on_portSearchTimer_timeout();
|
||||||
|
|
||||||
void on_Raw_CMDHistoryBox_stateChanged(int arg1);
|
void on_Raw_CMDHistoryBox_stateChanged(int arg1);
|
||||||
|
|
||||||
@@ -73,7 +85,7 @@ private slots:
|
|||||||
|
|
||||||
void on_MF_Sniff_listButton_clicked();
|
void on_MF_Sniff_listButton_clicked();
|
||||||
|
|
||||||
void on_MF_RW_readAllButton_clicked();
|
void on_MF_RW_readSelectedButton_clicked();
|
||||||
|
|
||||||
void on_MF_RW_readBlockButton_clicked();
|
void on_MF_RW_readBlockButton_clicked();
|
||||||
|
|
||||||
@@ -81,18 +93,17 @@ private slots:
|
|||||||
|
|
||||||
void on_MF_Attack_infoButton_clicked();
|
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_dumpButton_clicked();
|
||||||
|
|
||||||
void on_MF_RW_restoreButton_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_readBlockButton_clicked();
|
||||||
|
|
||||||
void on_MF_UID_writeAllButton_clicked();
|
void on_MF_UID_writeSelectedButton_clicked();
|
||||||
|
|
||||||
void on_MF_UID_writeBlockButton_clicked();
|
void on_MF_UID_writeBlockButton_clicked();
|
||||||
|
|
||||||
@@ -100,9 +111,9 @@ private slots:
|
|||||||
|
|
||||||
void on_MF_File_saveButton_clicked();
|
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);
|
void on_MF_dataWidget_itemChanged(QTableWidgetItem *item);
|
||||||
|
|
||||||
@@ -120,9 +131,9 @@ private slots:
|
|||||||
|
|
||||||
void on_MF_UID_lockButton_clicked();
|
void on_MF_UID_lockButton_clicked();
|
||||||
|
|
||||||
void on_MF_Sim_loadDataButton_clicked();
|
void on_MF_Sim_readSelectedButton_clicked();
|
||||||
|
|
||||||
void on_MF_Sim_writeAllButton_clicked();
|
void on_MF_Sim_writeSelectedButton_clicked();
|
||||||
|
|
||||||
void on_MF_Sim_clearButton_clicked();
|
void on_MF_Sim_clearButton_clicked();
|
||||||
|
|
||||||
@@ -132,31 +143,83 @@ private slots:
|
|||||||
|
|
||||||
void on_MF_Sniff_saveButton_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:
|
private:
|
||||||
Ui::MainWindow* ui;
|
Ui::MainWindow* ui;
|
||||||
QButtonGroup* typeBtnGroup;
|
QButtonGroup* MFCardTypeBtnGroup;
|
||||||
QLabel* connectStatusBar;
|
QLabel* connectStatusBar;
|
||||||
QLabel* programStatusBar;
|
QLabel* programStatusBar;
|
||||||
QLabel* PM3VersionBar;
|
QLabel* PM3VersionBar;
|
||||||
|
QPushButton* stopButton;
|
||||||
QAction* myInfo;
|
QAction* myInfo;
|
||||||
|
QAction* currVersion;
|
||||||
|
QAction* checkUpdate;
|
||||||
|
QSettings* settings;
|
||||||
|
MyEventFilter* keyEventFilter;
|
||||||
|
MyEventFilter* resizeEventFilter;
|
||||||
|
|
||||||
|
QString stashedCMDEditText;
|
||||||
|
int stashedIndex = -1;
|
||||||
|
|
||||||
void uiInit();
|
void uiInit();
|
||||||
|
|
||||||
PM3Process* pm3;
|
PM3Process* pm3;
|
||||||
bool pm3state;
|
bool pm3state;
|
||||||
|
bool keepButtonsEnabled;
|
||||||
QThread* pm3Thread;
|
QThread* pm3Thread;
|
||||||
|
QTimer* portSearchTimer;
|
||||||
|
QStringList portList;
|
||||||
|
QStringList clientEnv;
|
||||||
|
QDir* clientWorkingDir;
|
||||||
|
|
||||||
Mifare* mifare;
|
Mifare* mifare;
|
||||||
Util* util;
|
Util* util;
|
||||||
|
|
||||||
|
MF_trailerDecoderDialog* decDialog;
|
||||||
|
|
||||||
|
|
||||||
void signalInit();
|
void signalInit();
|
||||||
void MF_widgetReset();
|
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 setState(bool st);
|
||||||
|
void saveClientPath(const QString& path);
|
||||||
signals:
|
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 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
|
#endif // MAINWINDOW_H
|
||||||
|
|||||||
@@ -21,14 +21,26 @@ MF_Attack_hardnestedDialog::~MF_Attack_hardnestedDialog()
|
|||||||
|
|
||||||
void MF_Attack_hardnestedDialog::on_buttonBox_accepted()
|
void MF_Attack_hardnestedDialog::on_buttonBox_accepted()
|
||||||
{
|
{
|
||||||
emit sendCMD("hf mf hardnested "
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
+ ui->knownKeySectorBox->currentText()
|
emit sendCMD("hf mf hardnested "
|
||||||
+ " "
|
+ ui->knownKeySectorBox->currentText()
|
||||||
+ ui->knownKeyTypeBox->currentText()
|
+ " "
|
||||||
+ " "
|
+ ui->knownKeyTypeBox->currentText()
|
||||||
+ ui->knownKeyBox->text()
|
+ " "
|
||||||
+ " "
|
+ ui->knownKeyBox->text()
|
||||||
+ ui->targetKeySectorBox->currentText()
|
+ " "
|
||||||
+ " "
|
+ ui->targetKeySectorBox->currentText()
|
||||||
+ ui->targetKeyTypeBox->currentText());
|
+ " "
|
||||||
|
+ ui->targetKeyTypeBox->currentText());
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
|
||||||
|
emit sendCMD("hf mf hardnested "
|
||||||
|
+ ui->knownKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyTypeBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyBox->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeyTypeBox->currentText());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
#define MF_ATTACK_HARDNESTEDDIALOG_H
|
#define MF_ATTACK_HARDNESTEDDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class MF_Attack_hardnestedDialog;
|
class MF_Attack_hardnestedDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
Ui::MF_Attack_hardnestedDialog *ui;
|
Ui::MF_Attack_hardnestedDialog *ui;
|
||||||
signals:
|
signals:
|
||||||
void sendCMD(QString cmd);
|
void sendCMD(const QString& cmd);
|
||||||
private slots:
|
private slots:
|
||||||
void on_buttonBox_accepted();
|
void on_buttonBox_accepted();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,34 @@
|
|||||||
#include "mf_sim_simdialog.h"
|
#include "mf_sim_simdialog.h"
|
||||||
#include "ui_mf_sim_simdialog.h"
|
#include "ui_mf_sim_simdialog.h"
|
||||||
|
|
||||||
MF_Sim_simDialog::MF_Sim_simDialog(int cardType, QWidget *parent) :
|
MF_Sim_simDialog::MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::MF_Sim_simDialog)
|
ui(new Ui::MF_Sim_simDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
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->cardType = cardType;
|
||||||
|
this->cardTypeText = cardTypeText;
|
||||||
}
|
}
|
||||||
|
|
||||||
MF_Sim_simDialog::~MF_Sim_simDialog()
|
MF_Sim_simDialog::~MF_Sim_simDialog()
|
||||||
@@ -55,12 +77,27 @@ void MF_Sim_simDialog::on_fBox_clicked(bool checked)
|
|||||||
void MF_Sim_simDialog::on_buttonBox_accepted()
|
void MF_Sim_simDialog::on_buttonBox_accepted()
|
||||||
{
|
{
|
||||||
QString paras;
|
QString paras;
|
||||||
paras += (ui->uBox->isChecked() ? "u " + ui->uEdit->text() + " " : "");
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
paras += (ui->nBox->isChecked() ? "n " + ui->nEdit->text() + " " : "");
|
{
|
||||||
paras += (ui->iBox->isChecked() ? "i " : "");
|
paras += (ui->uBox->isChecked() ? "u " + ui->uEdit->text() + " " : "");
|
||||||
paras += (ui->xBox->isChecked() ? "x " : "");
|
paras += (ui->nBox->isChecked() ? "n " + ui->nEdit->text() + " " : "");
|
||||||
paras += (ui->eBox->isChecked() ? "e " : "");
|
paras += (ui->iBox->isChecked() ? "i " : "");
|
||||||
paras += (ui->fBox->isChecked() ? "f " + ui->fEdit->text() + " " : "");
|
paras += (ui->xBox->isChecked() ? "x " : "");
|
||||||
paras += (ui->rBox->isChecked() ? "r " : "");
|
paras += (ui->eBox->isChecked() ? "e " : "");
|
||||||
emit sendCMD(QString("hf mf sim ") + "*" + QString::number(cardType) + " " + paras.trimmed());
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
@@ -14,7 +15,7 @@ class MF_Sim_simDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MF_Sim_simDialog(int cardType, QWidget *parent = nullptr);
|
explicit MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent = nullptr);
|
||||||
~MF_Sim_simDialog();
|
~MF_Sim_simDialog();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
@@ -25,8 +26,9 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
Ui::MF_Sim_simDialog *ui;
|
Ui::MF_Sim_simDialog *ui;
|
||||||
int cardType;
|
int cardType;
|
||||||
|
QString cardTypeText;
|
||||||
signals:
|
signals:
|
||||||
void sendCMD(QString cmd);
|
void sendCMD(const QString& cmd);
|
||||||
private slots:
|
private slots:
|
||||||
void on_buttonBox_accepted();
|
void on_buttonBox_accepted();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,309 +7,598 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>461</width>
|
<width>461</width>
|
||||||
<height>456</height>
|
<height>524</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Simulate</string>
|
<string>Simulate</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<property name="spacing">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<widget class="QGroupBox" name="uGroupBox">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="uLayout">
|
||||||
<widget class="QCheckBox" name="uBox">
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>5</number>
|
||||||
<string>u</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="topMargin">
|
||||||
<widget class="QLineEdit" name="uEdit">
|
<number>0</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<property name="rightMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="maximumSize">
|
</property>
|
||||||
<size>
|
<item>
|
||||||
<width>100</width>
|
<widget class="QCheckBox" name="uBox">
|
||||||
<height>16777215</height>
|
<property name="text">
|
||||||
</size>
|
<string>u</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLineEdit" name="uEdit">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="maximumSize">
|
||||||
<string>UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used</string>
|
<size>
|
||||||
</property>
|
<width>100</width>
|
||||||
<property name="wordWrap">
|
<height>16777215</height>
|
||||||
<bool>true</bool>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_6">
|
<widget class="Line" name="uLine">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<widget class="QGroupBox" name="atqaGroupBox">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="atqaLayout">
|
||||||
<widget class="QCheckBox" name="nBox">
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>5</number>
|
||||||
<string>n</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="topMargin">
|
||||||
<widget class="QLineEdit" name="nEdit">
|
<number>0</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<property name="rightMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="maximumSize">
|
</property>
|
||||||
<size>
|
<item>
|
||||||
<width>100</width>
|
<widget class="QCheckBox" name="atqaBox">
|
||||||
<height>16777215</height>
|
<property name="text">
|
||||||
</size>
|
<string>--atqa</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLineEdit" name="atqaEdit">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="maximumSize">
|
||||||
<string>Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite</string>
|
<size>
|
||||||
</property>
|
<width>100</width>
|
||||||
<property name="wordWrap">
|
<height>16777215</height>
|
||||||
<bool>true</bool>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_5">
|
<widget class="Line" name="atqaLine">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<widget class="QGroupBox" name="sakGroupBox">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="sakLayout">
|
||||||
<widget class="QCheckBox" name="iBox">
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>5</number>
|
||||||
<string>i</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="topMargin">
|
||||||
<widget class="QLabel" name="label_3">
|
<number>0</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<property name="rightMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Interactive, means that console will not be returned until simulation finishes or is aborted</string>
|
<item>
|
||||||
</property>
|
<widget class="QCheckBox" name="sakBox">
|
||||||
<property name="wordWrap">
|
<property name="text">
|
||||||
<bool>true</bool>
|
<string>--sak</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_4">
|
<widget class="Line" name="sakLine">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
<widget class="QGroupBox" name="nGroupBox">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="nLayout">
|
||||||
<widget class="QCheckBox" name="xBox">
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>5</number>
|
||||||
<string>x</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="topMargin">
|
||||||
<widget class="QLabel" name="label_4">
|
<number>0</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<property name="rightMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)</string>
|
<item>
|
||||||
</property>
|
<widget class="QCheckBox" name="nBox">
|
||||||
<property name="wordWrap">
|
<property name="text">
|
||||||
<bool>true</bool>
|
<string>n</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_3">
|
<widget class="Line" name="nLine">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
<widget class="QGroupBox" name="iGroupBox">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="iLayout">
|
||||||
<widget class="QCheckBox" name="eBox">
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>5</number>
|
||||||
<string>e</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="topMargin">
|
||||||
<widget class="QLabel" name="label_5">
|
<number>0</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<property name="rightMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>set keys found from 'reader attack' to emulator memory (implies x and i)</string>
|
<item>
|
||||||
</property>
|
<widget class="QCheckBox" name="iBox">
|
||||||
<property name="wordWrap">
|
<property name="text">
|
||||||
<bool>true</bool>
|
<string>i</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_2">
|
<widget class="Line" name="iLine">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<widget class="QGroupBox" name="xGroupBox">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="xLayout">
|
||||||
<widget class="QCheckBox" name="fBox">
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>5</number>
|
||||||
<string>f</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="topMargin">
|
||||||
<widget class="QLineEdit" name="fEdit">
|
<number>0</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<property name="rightMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="maximumSize">
|
</property>
|
||||||
<size>
|
<item>
|
||||||
<width>100</width>
|
<widget class="QCheckBox" name="xBox">
|
||||||
<height>16777215</height>
|
<property name="text">
|
||||||
</size>
|
<string>x</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)</string>
|
<string>Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line">
|
<widget class="Line" name="xLine">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
<widget class="QGroupBox" name="eGroupBox">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="eLayout">
|
||||||
<widget class="QCheckBox" name="rBox">
|
<property name="spacing">
|
||||||
<property name="text">
|
<number>5</number>
|
||||||
<string>r</string>
|
</property>
|
||||||
</property>
|
<property name="leftMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="topMargin">
|
||||||
<widget class="QLabel" name="label_7">
|
<number>0</number>
|
||||||
<property name="sizePolicy">
|
</property>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
<property name="rightMargin">
|
||||||
<horstretch>0</horstretch>
|
<number>0</number>
|
||||||
<verstretch>0</verstretch>
|
</property>
|
||||||
</sizepolicy>
|
<property name="bottomMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works</string>
|
<item>
|
||||||
</property>
|
<widget class="QCheckBox" name="eBox">
|
||||||
<property name="wordWrap">
|
<property name="text">
|
||||||
<bool>true</bool>
|
<string>e</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<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>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_7">
|
<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">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
|||||||
@@ -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,10 +18,18 @@ MF_UID_parameterDialog::~MF_UID_parameterDialog()
|
|||||||
|
|
||||||
void MF_UID_parameterDialog::on_buttonBox_accepted()
|
void MF_UID_parameterDialog::on_buttonBox_accepted()
|
||||||
{
|
{
|
||||||
emit sendCMD("hf mf csetuid "
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
+ ui->UIDLineEdit->text()
|
emit sendCMD("hf mf csetuid "
|
||||||
+ " "
|
+ ui->UIDLineEdit->text()
|
||||||
+ ui->ATQALineEdit->text()
|
+ " "
|
||||||
+ " "
|
+ ui->ATQALineEdit->text()
|
||||||
+ ui->SAKLineEdit->text());
|
+ " "
|
||||||
|
+ ui->SAKLineEdit->text());
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
|
||||||
|
emit sendCMD("hf mf csetuid "
|
||||||
|
+ ui->UIDLineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->ATQALineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->SAKLineEdit->text());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,10 @@
|
|||||||
#define MF_UID_PARAMETERDIALOG_H
|
#define MF_UID_PARAMETERDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui
|
||||||
|
{
|
||||||
class MF_UID_parameterDialog;
|
class MF_UID_parameterDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +20,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
Ui::MF_UID_parameterDialog *ui;
|
Ui::MF_UID_parameterDialog *ui;
|
||||||
signals:
|
signals:
|
||||||
void sendCMD(QString cmd);
|
void sendCMD(const QString& cmd);
|
||||||
private slots:
|
private slots:
|
||||||
void on_buttonBox_accepted();
|
void on_buttonBox_accepted();
|
||||||
};
|
};
|
||||||
|
|||||||