Compare commits
133 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bac6207634 | |||
| ccb07651cc | |||
| f706d59c48 | |||
| 9e31496131 | |||
| a232e4ec83 | |||
| 1bec73d1ad | |||
| a8b1a4a82e | |||
| 03bb57ee58 | |||
| 15538a9892 | |||
| 466cd0ecc1 | |||
| 019afed198 | |||
| 799e00d66e | |||
| ae9e4d1a4f | |||
| c3aafc3d31 | |||
| fb8e1a6e1b | |||
| 90e4fde882 | |||
| 705c8de54c | |||
| aa6b93984c | |||
| 7f96c061dc | |||
| b8c4e8e339 | |||
| 4f10e3d75c | |||
| 63f3424871 | |||
| 24a6e1869b | |||
| 6baa09221e | |||
| 6e5f654cc5 | |||
| 83445c7eef | |||
| 5330ed8d14 | |||
| a56a503b23 | |||
| 77d8049738 | |||
| bf9b3fb076 | |||
| 6d3dd5056c | |||
| e687cc39fd | |||
| 3c3944d150 | |||
| 091b4f63d1 | |||
| 0c4220c9a5 | |||
| 986e9aacfe | |||
| ce262db52c | |||
| 73533608e6 | |||
| 2f38d3c8c5 | |||
| f2d00ee088 | |||
| 862f0775f8 | |||
| a7985c5c89 | |||
| a3e6aa787b | |||
| 1c273a6527 | |||
| 3f899845b7 | |||
| 475580c342 | |||
| 3a577bdd32 | |||
| f8d2bbb206 | |||
| d6beafe175 | |||
| f881a05fa3 | |||
| ad10a6e789 | |||
| bf8136a7fe | |||
| 6af85bffc0 | |||
| 3751349004 | |||
| 44c61a8202 | |||
| fbe8a5e51d | |||
| 41bbcd2c4a | |||
| 4dba7882e5 | |||
| 25d7886f2a | |||
| 7e4dedeff1 | |||
| 7dfabb60e9 | |||
| 46b3912e82 | |||
| fe8f8b2d51 | |||
| d15b8e21fc | |||
| eb5fa7ec9a | |||
| ef6ebea568 | |||
| 6f860111df | |||
| a935ff9703 | |||
| 02b0c312a4 | |||
| 946d0acb01 | |||
| a60b28ee66 | |||
| 43752bd5e4 | |||
| a77985824c | |||
| cd122b8959 | |||
| 87dddf4d3d | |||
| b2baaede5d | |||
| 7ea9c363fd | |||
| 241b0cdc29 | |||
| 3181848e75 | |||
| 5cccb7b8bb | |||
| 461c48fee9 | |||
| 2790afc193 | |||
| 5816d1b1b6 | |||
| fe8b9d6161 | |||
| afe2474fe3 | |||
| 0995e529ad | |||
| b44488fbed | |||
| 5f1df6782a | |||
| bec81e6c7d | |||
| 0f2cca9a98 | |||
| 526bd89873 | |||
| a65bcffffd | |||
| 2b8e31e452 | |||
| e34c36e572 | |||
| 383eaff2a5 | |||
| c74cdee924 | |||
| 6080ac7d7c | |||
| c97c550439 | |||
| 6765a84a80 | |||
| 767a651735 | |||
| d793c41aa5 | |||
| 41015fd1fe | |||
| 05d44604a4 | |||
| 23eb3f8ab3 | |||
| ac7f1b33dd | |||
| b6be875261 | |||
| b2fa97ff18 | |||
| 0be1eb5041 | |||
| abfc940dc8 | |||
| a325e3b670 | |||
| a6302f8fa8 | |||
| ed1e9cb1d6 | |||
| a6a699d33c | |||
| 5c5fb84811 | |||
| 6b8e98b735 | |||
| 80a8db540f | |||
| b540741b1a | |||
| fd009745f9 | |||
| fc91bfee2c | |||
| c25e2f9e4a | |||
| 1d8d931752 | |||
| b3fd3ba378 | |||
| 01e6a134cd | |||
| 15a1950a23 | |||
| 037731de64 | |||
| 4aa5654ffd | |||
| 5d793eb764 | |||
| d9e993be9a | |||
| d2689c333c | |||
| e09fdf1b9b | |||
| 643c298662 | |||
| d651d2788d | |||
| db356a2e55 |
@@ -14,7 +14,6 @@
|
|||||||
*.so.*
|
*.so.*
|
||||||
*_pch.h.cpp
|
*_pch.h.cpp
|
||||||
*_resource.rc
|
*_resource.rc
|
||||||
*.qm
|
|
||||||
.#*
|
.#*
|
||||||
*.*#
|
*.*#
|
||||||
core
|
core
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 wh201906
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -16,23 +16,47 @@ 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 \
|
||||||
mainwindow.cpp \
|
common/pm3process.cpp \
|
||||||
pm3process.cpp
|
common/util.cpp \
|
||||||
|
module/lf.cpp \
|
||||||
|
module/mifare.cpp \
|
||||||
|
ui/mf_trailerdecoderdialog.cpp \
|
||||||
|
ui/mf_sim_simdialog.cpp \
|
||||||
|
ui/mf_uid_parameterdialog.cpp \
|
||||||
|
ui/mainwindow.cpp \
|
||||||
|
ui/mf_attack_hardnesteddialog.cpp \
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
mainwindow.h \
|
common/myeventfilter.h \
|
||||||
pm3process.h
|
common/pm3process.h \
|
||||||
|
common/util.h \
|
||||||
|
module/lf.h \
|
||||||
|
module/mifare.h \
|
||||||
|
ui/mf_trailerdecoderdialog.h \
|
||||||
|
ui/mf_sim_simdialog.h \
|
||||||
|
ui/mf_uid_parameterdialog.h \
|
||||||
|
ui/mainwindow.h \
|
||||||
|
ui/mf_attack_hardnesteddialog.h \
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
mainwindow.ui
|
ui/mf_trailerdecoderdialog.ui \
|
||||||
|
ui/mf_sim_simdialog.ui \
|
||||||
|
ui/mf_uid_parameterdialog.ui \
|
||||||
|
ui/mainwindow.ui \
|
||||||
|
ui/mf_attack_hardnesteddialog.ui
|
||||||
|
|
||||||
|
TRANSLATIONS += \
|
||||||
|
lang/zh_CN.ts \
|
||||||
|
lang/en_US.ts
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
!isEmpty(target.path): INSTALLS += target
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
VERSION = 0.0.1
|
VERSION = 0.2.1
|
||||||
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
||||||
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
||||||
QMAKE_TARGET_COMPANY = "wh201906"
|
QMAKE_TARGET_COMPANY = "wh201906"
|
||||||
|
|||||||
@@ -1,9 +1,109 @@
|
|||||||
# Proxmark3GUI
|
# Proxmark3GUI
|
||||||
A GUI for Proxmark3 client
|

|
||||||
|
|
||||||
|
A cross-platform GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client
|
||||||
|
|
||||||
|
[中文介绍](README/doc/README_zh_CN.md)
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
Update Log:
|
## Features
|
||||||
|
|
||||||
## V0.0.1
|
+ Easy to find available Serial Port
|
||||||
|
+ Support raw commands of Proxmark3 client(Official/Iceman)
|
||||||
|
+ Have a friendly UI to test Mifare cards
|
||||||
|
+ Support different card size(MINI, 1K, 2K, 4K)
|
||||||
|
+ Easy to edit Mifare block data
|
||||||
|
+ Easy to read all/selected blocks with well-designed read logic
|
||||||
|
+ Easy to write all/selected blocks
|
||||||
|
+ Support binary(.bin .dump) files and text(.eml) files
|
||||||
|
+ Analyze Access Bits
|
||||||
|
+ Support Chinese Magic Card
|
||||||
|
+ Have basic support for LF commands
|
||||||
|
+ Customize UI
|
||||||
|
+ ...
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 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 the client on Windows.
|
||||||
|
Also, he makes the [pre-compiled Windows client](https://www.proxmarkbuilds.org/) so you can download it and run your PM3 client on Windows instantly.
|
||||||
|
I included his compiled client in my releases so you can use the GUI on the fly, and you can also use the GUI with your prefered client.
|
||||||
|
Great thanks to him.
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Build on Linux
|
||||||
|
|
||||||
|
cd ~
|
||||||
|
git clone https://github.com/wh201906/Proxmark3GUI.git
|
||||||
|
cd Proxmark3GUI
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
qmake ../
|
||||||
|
make
|
||||||
|
make clean
|
||||||
|
cp -r ../lang ./
|
||||||
|
./Proxmark3GUI
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## Update Log:
|
||||||
|
|
||||||
|
### V0.2.1
|
||||||
|
+ Optimize MIFARE Classic reading logic
|
||||||
|
+ Fix bug #16
|
||||||
|
+ Fix bug #15 partially (the path can contain spaces now)
|
||||||
|
|
||||||
|
### V0.2
|
||||||
|
+ Use Dock widget for more flexible layout
|
||||||
|
+ Support basic LF commands
|
||||||
|
+ Fix a bug in RawCommand tab
|
||||||
|
|
||||||
|
### V0.1.4
|
||||||
|
+ Optimize performance
|
||||||
|
+ Optimize UI
|
||||||
|
+ Search available ports automatically
|
||||||
|
+ Add High-DPI support
|
||||||
|
+ Support configuring environment variables by script
|
||||||
|
(Useful when the client requires specific environment variables)
|
||||||
|
+ All functions are compatible with Iceman/RRG repo(tested on v4.9237)
|
||||||
|
+ Support specifying client working directory
|
||||||
|
+ Fix some bugs
|
||||||
|
|
||||||
|
### V0.1.3
|
||||||
|
+ Fix Trailer Decoder
|
||||||
|
+ Add feedback when writing selected blocks
|
||||||
|
|
||||||
|
### V0.1.2
|
||||||
|
+ Optimize read logic
|
||||||
|
+ Make UI Customizable
|
||||||
|
+ Save client path automatically
|
||||||
|
+ Add Trailer Decoder(Deprecated, plz use V0.1.3 or higher version)
|
||||||
|
+ Support read/write selected blocks
|
||||||
|
+ Support a few Iceman functions
|
||||||
|
+ Fix some bugs
|
||||||
|
|
||||||
|
### V0.1.1
|
||||||
|
+ Complete Mifare module(support simulate and sniff)
|
||||||
|
|
||||||
|
### V0.1
|
||||||
|
+ Able to deal with Mifare card and related files
|
||||||
|
|
||||||
|
### V0.0.1
|
||||||
+ a dumb version with a useless GUI and a serial choose box.
|
+ a dumb version with a useless GUI and a serial choose box.
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
# 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.2.1
|
||||||
|
+ 优化MIFARE Classic读卡逻辑
|
||||||
|
+ 修复 #16 (配合新版RRG固件时无法读取扇区数据)
|
||||||
|
+ 修复 #15 (路径中支持空格)
|
||||||
|
|
||||||
|
### V0.2
|
||||||
|
+ 使用浮动窗口,界面配置更加灵活
|
||||||
|
+ 支持部分低频命令
|
||||||
|
+ 修复原始命令选项卡中的一个Bug
|
||||||
|
|
||||||
|
### 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,20 @@
|
|||||||
|
## Previews
|
||||||
|
|
||||||
|
Raw Command:
|
||||||
|

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

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

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

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

|
||||||
|
|
||||||
|
Dock Widget:
|
||||||
|

|
||||||
|

|
||||||
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
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: 44 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 345 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
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
#include "pm3process.h"
|
||||||
|
|
||||||
|
PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent)
|
||||||
|
{
|
||||||
|
moveToThread(thread);
|
||||||
|
setProcessChannelMode(PM3Process::MergedChannels);
|
||||||
|
isRequiringOutput = false;
|
||||||
|
requiredOutput = new QString();
|
||||||
|
serialListener = new QTimer(); // if using new QTimer(this), the debug output will show "Cannot create children for a parent that is in a different thread."
|
||||||
|
serialListener->moveToThread(this->thread());// I've tried many ways to creat a QTimer instance, but all of the instances are in the main thread(UI thread), so I have to move it manually
|
||||||
|
serialListener->setInterval(1000);
|
||||||
|
serialListener->setTimerType(Qt::VeryCoarseTimer);
|
||||||
|
connect(serialListener, &QTimer::timeout, this, &PM3Process::onTimeout);
|
||||||
|
connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead);
|
||||||
|
portInfo = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::connectPM3(const QString& path, const QStringList args)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
Util::ClientType clientType;
|
||||||
|
setRequiringOutput(true);
|
||||||
|
|
||||||
|
// stash for reconnect
|
||||||
|
currPath = path;
|
||||||
|
currArgs = args;
|
||||||
|
|
||||||
|
// using "-f" option to make the client output flushed after every print.
|
||||||
|
start(path, args, QProcess::Unbuffered | QProcess::ReadWrite);
|
||||||
|
if(waitForStarted(10000))
|
||||||
|
{
|
||||||
|
waitForReadyRead(10000);
|
||||||
|
setRequiringOutput(false);
|
||||||
|
result = *requiredOutput;
|
||||||
|
if(result.indexOf("[=]") != -1)
|
||||||
|
{
|
||||||
|
clientType = Util::CLIENTTYPE_ICEMAN;
|
||||||
|
setRequiringOutput(true);
|
||||||
|
write("hw version\r\n");
|
||||||
|
for(int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
waitForReadyRead(200);
|
||||||
|
result += *requiredOutput;
|
||||||
|
}
|
||||||
|
setRequiringOutput(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clientType = Util::CLIENTTYPE_OFFICIAL;
|
||||||
|
}
|
||||||
|
if(result.indexOf("os: ") != -1) // make sure the PM3 is connected
|
||||||
|
{
|
||||||
|
emit changeClientType(clientType);
|
||||||
|
result = result.mid(result.indexOf("os: "));
|
||||||
|
result = result.left(result.indexOf("\r\n"));
|
||||||
|
result = result.mid(3, result.lastIndexOf(" ") - 3);
|
||||||
|
emit PM3StatedChanged(true, result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::reconnectPM3()
|
||||||
|
{
|
||||||
|
connectPM3(currPath, currArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::setRequiringOutput(bool st)
|
||||||
|
{
|
||||||
|
isRequiringOutput = st;
|
||||||
|
if(isRequiringOutput)
|
||||||
|
requiredOutput->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PM3Process::waitForReadyRead(int msecs)
|
||||||
|
{
|
||||||
|
return QProcess::waitForReadyRead(msecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::setSerialListener(const QString& name, bool state)
|
||||||
|
{
|
||||||
|
if(state)
|
||||||
|
{
|
||||||
|
currPort = name;
|
||||||
|
portInfo = new QSerialPortInfo(name);
|
||||||
|
serialListener->start();
|
||||||
|
qDebug() << serialListener->thread();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serialListener->stop();
|
||||||
|
if(portInfo != nullptr)
|
||||||
|
{
|
||||||
|
delete portInfo;
|
||||||
|
portInfo = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::setSerialListener(bool state)
|
||||||
|
{
|
||||||
|
setSerialListener(currPort, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::onTimeout() //when the proxmark3 client is unexpectedly terminated or the PM3 hardware is removed, the isBusy() will return false(only tested on Windows);
|
||||||
|
{
|
||||||
|
// qDebug()<<portInfo->isBusy();
|
||||||
|
if(!portInfo->isBusy())
|
||||||
|
{
|
||||||
|
killPM3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::testThread()
|
||||||
|
{
|
||||||
|
qDebug() << "PM3:" << QThread::currentThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 PM3Process::write(QString data)
|
||||||
|
{
|
||||||
|
return QProcess::write(data.toLatin1());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::onReadyRead()
|
||||||
|
{
|
||||||
|
QString out = readAll();
|
||||||
|
if(isRequiringOutput)
|
||||||
|
requiredOutput->append(out);
|
||||||
|
if(out != "")
|
||||||
|
{
|
||||||
|
// qDebug() << "PM3Process::onReadyRead:" << out;
|
||||||
|
emit newOutput(out);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PM3Process::killPM3()
|
||||||
|
{
|
||||||
|
kill();
|
||||||
|
emit PM3StatedChanged(false);
|
||||||
|
setSerialListener(false);
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#ifndef PM3PROCESS_H
|
||||||
|
#define PM3PROCESS_H
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QtSerialPort/QSerialPortInfo>
|
||||||
|
#include <QtSerialPort/QSerialPort>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
class PM3Process : public QProcess
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit PM3Process(QThread* thread, QObject* parent = nullptr);
|
||||||
|
bool waitForReadyRead(int msecs = 2000);
|
||||||
|
|
||||||
|
void testThread();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void connectPM3(const QString& path, const QStringList args);
|
||||||
|
void setSerialListener(const QString& name, bool state);
|
||||||
|
void setSerialListener(bool state);
|
||||||
|
qint64 write(QString data);
|
||||||
|
void reconnectPM3();
|
||||||
|
void setProcEnv(const QStringList* env);
|
||||||
|
void setWorkingDir(const QString& dir);
|
||||||
|
void killPM3();
|
||||||
|
private slots:
|
||||||
|
void onTimeout();
|
||||||
|
void onReadyRead();
|
||||||
|
private:
|
||||||
|
bool isRequiringOutput;
|
||||||
|
QString* requiredOutput; // It only works in this class now
|
||||||
|
void setRequiringOutput(bool st);// It only works in this class now
|
||||||
|
QTimer* serialListener;
|
||||||
|
QSerialPortInfo* portInfo;
|
||||||
|
QString currPath;
|
||||||
|
QString currPort = "";
|
||||||
|
QStringList currArgs;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void PM3StatedChanged(bool st, const QString& info = "");
|
||||||
|
void newOutput(const QString& output);
|
||||||
|
void changeClientType(Util::ClientType);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PM3PROCESS_H
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
Util::ClientType Util::clientType = CLIENTTYPE_OFFICIAL;
|
||||||
|
|
||||||
|
int Util::rawTabIndex = 0;
|
||||||
|
QDockWidget* Util::rawDockPtr = nullptr;
|
||||||
|
Ui::MainWindow* Util::ui = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
Util::Util(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
isRequiringOutput = false;
|
||||||
|
requiredOutput = new QString();
|
||||||
|
timeStamp = QTime::currentTime();
|
||||||
|
qRegisterMetaType<Util::ClientType>("Util::ClientType");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Util::processOutput(const QString& output)
|
||||||
|
{
|
||||||
|
// qDebug() << "Util::processOutput:" << output;
|
||||||
|
if(isRequiringOutput)
|
||||||
|
{
|
||||||
|
requiredOutput->append(output);
|
||||||
|
timeStamp = QTime::currentTime();
|
||||||
|
}
|
||||||
|
emit refreshOutput(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::execCMD(const QString& cmd)
|
||||||
|
{
|
||||||
|
qDebug() << "executing: " << cmd;
|
||||||
|
if(isRunning)
|
||||||
|
emit write(cmd + "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Util::execCMDWithOutput(const QString& cmd, ReturnTrigger trigger)
|
||||||
|
{
|
||||||
|
// if the trigger is empty, this function will wait trigger.waitTime then return all outputs during the wait time.
|
||||||
|
// otherwise, this function will return empty string if no trigger is detected, or return outputs if any trigger is detected.
|
||||||
|
// the waitTime will be refreshed if the client have new outputs
|
||||||
|
bool isResultFound = false;
|
||||||
|
QRegularExpression re;
|
||||||
|
re.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
|
||||||
|
|
||||||
|
if(!isRunning)
|
||||||
|
return "";
|
||||||
|
QTime currTime = QTime::currentTime();
|
||||||
|
QTime targetTime = QTime::currentTime().addMSecs(trigger.waitTime);
|
||||||
|
isRequiringOutput = true;
|
||||||
|
requiredOutput->clear();
|
||||||
|
execCMD(cmd);
|
||||||
|
while(QTime::currentTime() < targetTime)
|
||||||
|
{
|
||||||
|
if(!isRunning)
|
||||||
|
break;
|
||||||
|
QApplication::processEvents();
|
||||||
|
// qDebug() << "currOutput:" << *requiredOutput;
|
||||||
|
for(QString otpt : trigger.expectedOutputs)
|
||||||
|
{
|
||||||
|
re.setPattern(otpt);
|
||||||
|
isResultFound = re.match(*requiredOutput).hasMatch();
|
||||||
|
if(isResultFound)
|
||||||
|
{
|
||||||
|
qDebug() << "output Matched: " << *requiredOutput;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(isResultFound)
|
||||||
|
{
|
||||||
|
delay(200);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(timeStamp > currTime) //has new output
|
||||||
|
{
|
||||||
|
currTime = timeStamp;
|
||||||
|
targetTime = timeStamp.addMSecs(trigger.waitTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isRequiringOutput = false;
|
||||||
|
return (isResultFound || trigger.expectedOutputs.isEmpty() ? *requiredOutput : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::delay(unsigned int msec)
|
||||||
|
{
|
||||||
|
QTime timer = QTime::currentTime().addMSecs(msec);
|
||||||
|
while(QTime::currentTime() < timer)
|
||||||
|
QApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
Util::ClientType Util::getClientType()
|
||||||
|
{
|
||||||
|
return Util::clientType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::setClientType(Util::ClientType clientType)
|
||||||
|
{
|
||||||
|
Util::clientType = clientType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::setRunningState(bool st)
|
||||||
|
{
|
||||||
|
this->isRunning = st;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Util::chooseLanguage(QSettings* guiSettings, QMainWindow* window)
|
||||||
|
{
|
||||||
|
// make sure the GUISettings is not in any group
|
||||||
|
QSettings* langSettings = new QSettings("lang/languages.ini", QSettings::IniFormat);
|
||||||
|
QMap<QString, QString> langMap;
|
||||||
|
langSettings->setIniCodec("UTF-8");
|
||||||
|
langSettings->beginGroup("Languages");
|
||||||
|
QStringList langList = langSettings->allKeys();
|
||||||
|
for(int i = 0; i < langList.size(); i++)
|
||||||
|
langMap.insert(langSettings->value(langList[i]).toString(), langList[i]);
|
||||||
|
langSettings->endGroup();
|
||||||
|
delete langSettings;
|
||||||
|
bool isOk = false;
|
||||||
|
QString selectedText = QInputDialog::getItem(window, "", "Choose a language:", langMap.keys(), 0, false, &isOk);
|
||||||
|
if(isOk)
|
||||||
|
{
|
||||||
|
guiSettings->beginGroup("lang");
|
||||||
|
guiSettings->setValue("language", langMap[selectedText]);
|
||||||
|
guiSettings->endGroup();
|
||||||
|
guiSettings->sync();
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::gotoRawTab()
|
||||||
|
{
|
||||||
|
Util::ui->funcTab->setCurrentIndex(Util::rawTabIndex);
|
||||||
|
Util::rawDockPtr->setVisible(true);
|
||||||
|
Util::rawDockPtr->raise();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::setUI(Ui::MainWindow *ui)
|
||||||
|
{
|
||||||
|
Util::ui = ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Util::setRawTab(QDockWidget *dockPtr, int tabIndex)
|
||||||
|
{
|
||||||
|
Util::rawDockPtr = dockPtr;
|
||||||
|
Util::rawTabIndex = tabIndex;
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#ifndef UTIL_H
|
||||||
|
#define UTIL_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QTime>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QDockWidget>
|
||||||
|
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
class Util : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum ClientType
|
||||||
|
{
|
||||||
|
CLIENTTYPE_OFFICIAL,
|
||||||
|
CLIENTTYPE_ICEMAN,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ReturnTrigger
|
||||||
|
{
|
||||||
|
unsigned long waitTime;
|
||||||
|
QStringList expectedOutputs;
|
||||||
|
ReturnTrigger(unsigned long time)
|
||||||
|
{
|
||||||
|
waitTime = time;
|
||||||
|
expectedOutputs = QStringList();
|
||||||
|
}
|
||||||
|
ReturnTrigger(const QStringList& outputs)
|
||||||
|
{
|
||||||
|
waitTime = 10000;
|
||||||
|
expectedOutputs = outputs;
|
||||||
|
}
|
||||||
|
ReturnTrigger(unsigned long time, const QStringList& outputs)
|
||||||
|
{
|
||||||
|
waitTime = time;
|
||||||
|
expectedOutputs = outputs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM(Util::ClientType)
|
||||||
|
|
||||||
|
explicit Util(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
void execCMD(const QString& cmd);
|
||||||
|
QString execCMDWithOutput(const QString& cmd, ReturnTrigger trigger = 10000);
|
||||||
|
void delay(unsigned int msec);
|
||||||
|
static ClientType getClientType();
|
||||||
|
static int rawTabIndex;
|
||||||
|
static QDockWidget* rawDockPtr;
|
||||||
|
static bool chooseLanguage(QSettings *guiSettings, QMainWindow *window);
|
||||||
|
public slots:
|
||||||
|
void processOutput(const QString& output);
|
||||||
|
static void setClientType(Util::ClientType clientType);
|
||||||
|
void setRunningState(bool st);
|
||||||
|
static void gotoRawTab();
|
||||||
|
static void setUI(Ui::MainWindow *ui);
|
||||||
|
static void setRawTab(QDockWidget* dockPtr, int tabIndex);
|
||||||
|
private:
|
||||||
|
bool isRequiringOutput;
|
||||||
|
bool isRunning;
|
||||||
|
QString* requiredOutput;
|
||||||
|
QTime timeStamp;
|
||||||
|
static ClientType clientType;
|
||||||
|
static Ui::MainWindow *ui;
|
||||||
|
signals:
|
||||||
|
void refreshOutput(const QString& output);
|
||||||
|
void write(QString data); // connected to PM3Process::write(QString data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UTIL_H
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[Languages]
|
||||||
|
en_US=English
|
||||||
|
zh_CN=简体中文
|
||||||
@@ -1,11 +1,53 @@
|
|||||||
#include "mainwindow.h"
|
#include "ui/mainwindow.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QTranslator>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#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);
|
||||||
|
settings->setIniCodec("UTF-8");
|
||||||
|
settings->beginGroup("lang");
|
||||||
|
QString currLang = settings->value("language", "").toString();
|
||||||
|
settings->endGroup();
|
||||||
|
if(currLang == "")
|
||||||
|
{
|
||||||
|
if(Util::chooseLanguage(settings, &w))
|
||||||
|
{
|
||||||
|
settings->beginGroup("lang");
|
||||||
|
currLang = settings->value("language", "").toString();
|
||||||
|
settings->endGroup();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
currLang = "en_US";
|
||||||
|
}
|
||||||
|
currLang = "lang/" + currLang;
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
currLang += ".qm";
|
||||||
|
#else
|
||||||
|
currLang += ".ts";;
|
||||||
|
#endif
|
||||||
|
QTranslator* translator = new QTranslator(&w);
|
||||||
|
if(translator->load(currLang))
|
||||||
|
{
|
||||||
|
a.installTranslator(translator);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::information(&w, "Error", "Can't load " + currLang + " as translation file.");
|
||||||
|
}
|
||||||
|
delete settings;
|
||||||
|
w.initUI();
|
||||||
w.show();
|
w.show();
|
||||||
return a.exec();
|
return a.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
#include "mainwindow.h"
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
|
||||||
: QMainWindow(parent)
|
|
||||||
, ui(new Ui::MainWindow)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
pm3=new PM3Process;
|
|
||||||
connect(pm3,&PM3Process::readyRead,this,&MainWindow::refresh);
|
|
||||||
connect(ui->commandEdit,&QLineEdit::editingFinished,this,&MainWindow::sendMSG);
|
|
||||||
ui->portBox->addItem("");
|
|
||||||
foreach(QString port,pm3->findPort())
|
|
||||||
{
|
|
||||||
ui->portBox->addItem(port);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_connectButton_clicked()
|
|
||||||
{
|
|
||||||
QString port=ui->portBox->currentText();
|
|
||||||
if(port=="")
|
|
||||||
QMessageBox::information(NULL, "Info", "Plz choose a port first", QMessageBox::Ok);
|
|
||||||
else
|
|
||||||
qDebug()<<pm3->start(ui->PM3PathEdit->text(),port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_sendButton_clicked()
|
|
||||||
{
|
|
||||||
qDebug()<<(ui->commandEdit->text().toLocal8Bit());
|
|
||||||
pm3->write((ui->commandEdit->text()+"\r\n").toLocal8Bit());
|
|
||||||
pm3->waitForBytesWritten(3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::refresh()
|
|
||||||
{
|
|
||||||
QByteArray btay=pm3->readLine();
|
|
||||||
while(btay!="")
|
|
||||||
{
|
|
||||||
qDebug()<<btay;
|
|
||||||
ui->outputEdit->insertPlainText(btay);
|
|
||||||
btay=pm3->readLine();
|
|
||||||
}
|
|
||||||
ui->outputEdit->moveCursor(QTextCursor::End);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::sendMSG()
|
|
||||||
{
|
|
||||||
if(ui->commandEdit->hasFocus())
|
|
||||||
on_sendButton_clicked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_disconnectButton_clicked()
|
|
||||||
{
|
|
||||||
pm3->kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::on_clearButton_clicked()
|
|
||||||
{
|
|
||||||
ui->outputEdit->clear();
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#ifndef MAINWINDOW_H
|
|
||||||
#define MAINWINDOW_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include "pm3process.h"
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
namespace Ui { class MainWindow; }
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
MainWindow(QWidget *parent = nullptr);
|
|
||||||
~MainWindow();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void refresh();
|
|
||||||
private slots:
|
|
||||||
void on_connectButton_clicked();
|
|
||||||
|
|
||||||
void on_sendButton_clicked();
|
|
||||||
|
|
||||||
void on_disconnectButton_clicked();
|
|
||||||
|
|
||||||
void on_clearButton_clicked();
|
|
||||||
|
|
||||||
void sendMSG();
|
|
||||||
private:
|
|
||||||
Ui::MainWindow *ui;
|
|
||||||
PM3Process* pm3;
|
|
||||||
};
|
|
||||||
#endif // MAINWINDOW_H
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>MainWindow</class>
|
|
||||||
<widget class="QMainWindow" name="MainWindow">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>450</width>
|
|
||||||
<height>310</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>450</width>
|
|
||||||
<height>300</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Proxmark3GUI</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="centralwidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="sizeConstraint">
|
|
||||||
<enum>QLayout::SetMaximumSize</enum>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Path:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="PM3PathEdit">
|
|
||||||
<property name="text">
|
|
||||||
<string>proxmark3</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="portBox"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="connectButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Connect</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="disconnectButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Disconnect</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QTabWidget" name="funcTab">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="tab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>Tab 1</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="rawTab">
|
|
||||||
<attribute name="title">
|
|
||||||
<string>RawCommand</string>
|
|
||||||
</attribute>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPlainTextEdit" name="outputEdit">
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QAbstractScrollArea::AdjustIgnored</enum>
|
|
||||||
</property>
|
|
||||||
<property name="readOnly">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<property name="sizeConstraint">
|
|
||||||
<enum>QLayout::SetMaximumSize</enum>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="commandEdit"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="sendButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>Send</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="clearButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>ClearOutput</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenuBar" name="menubar">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>450</width>
|
|
||||||
<height>22</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
#include "lf.h"
|
||||||
|
|
||||||
|
const LF::Config LF::defaultConfig;
|
||||||
|
|
||||||
|
LF::LF(Ui::MainWindow *ui, Util *addr, QWidget *parent): QObject(parent)
|
||||||
|
{
|
||||||
|
this->parent = parent;
|
||||||
|
util = addr;
|
||||||
|
this->ui = ui;
|
||||||
|
|
||||||
|
configPattern = new QRegularExpression("(\\d+)|Yes|No");
|
||||||
|
currConfig = defaultConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::read()
|
||||||
|
{
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
util->execCMD("lf read");
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
util->execCMD("lf read -v");
|
||||||
|
Util::gotoRawTab();
|
||||||
|
util->execCMD("data plot");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::sniff()
|
||||||
|
{
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
util->execCMD("lf snoop");
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
util->execCMD("lf sniff -v");
|
||||||
|
Util::gotoRawTab();
|
||||||
|
util->execCMD("data plot");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::search()
|
||||||
|
{
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
util->execCMD("lf search u");
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
util->execCMD("lf search -u");
|
||||||
|
Util::gotoRawTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::tune()
|
||||||
|
{
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
util->execCMD("hw tune l");
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
util->execCMD("lf tune --divisor " + QString::number(currConfig.divisor));
|
||||||
|
Util::gotoRawTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::getConfig()
|
||||||
|
{
|
||||||
|
QRegularExpressionMatch reMatch;
|
||||||
|
QString result;
|
||||||
|
QStringList resultList;
|
||||||
|
QStringList symbolList =
|
||||||
|
{
|
||||||
|
"divisor",
|
||||||
|
"bps",
|
||||||
|
"bits per sample",
|
||||||
|
"decimation",
|
||||||
|
"averaging",
|
||||||
|
"trigger threshold",
|
||||||
|
"samples to skip"
|
||||||
|
};
|
||||||
|
int offset;
|
||||||
|
QStringList configList = {"", "", "", "", "", "", ""};
|
||||||
|
result = util->execCMDWithOutput("hw status", 400); // not all output from "hw status will be processed".
|
||||||
|
result = result.right(result.length() - result.indexOf("LF Sampling config"));
|
||||||
|
offset = result.indexOf("samples to skip");
|
||||||
|
offset = result.indexOf("\r\n", offset);
|
||||||
|
result = result.mid(0, offset + 2);
|
||||||
|
qDebug() << "LF CONFIG GET\n" << result;
|
||||||
|
resultList = result.split("\r\n");
|
||||||
|
for(int i = 0; i < resultList.length(); i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < symbolList.length(); j++)
|
||||||
|
{
|
||||||
|
if(!configList[j].isEmpty())
|
||||||
|
continue;
|
||||||
|
offset = resultList[i].indexOf(symbolList[j]);
|
||||||
|
if(offset != -1)
|
||||||
|
{
|
||||||
|
reMatch = configPattern->match(resultList[i]);
|
||||||
|
qDebug() << "finded: " << resultList[i];
|
||||||
|
if(!reMatch.hasMatch())
|
||||||
|
continue;
|
||||||
|
qDebug() << "captured: " << reMatch.captured();
|
||||||
|
configList[j] = reMatch.captured();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qDebug() << "configList: " << configList;
|
||||||
|
currConfig.divisor = configList[0].toUInt();
|
||||||
|
currConfig.decimation = configList[3].toUInt();
|
||||||
|
currConfig.triggerThreshold = configList[5].toUInt();
|
||||||
|
currConfig.samplesToSkip = configList[6].toUInt();
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
{
|
||||||
|
currConfig.bitPerSample = configList[1].toUInt();
|
||||||
|
currConfig.averaging = (configList[4] == "1");
|
||||||
|
}
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
{
|
||||||
|
currConfig.bitPerSample = configList[2].toUInt();
|
||||||
|
currConfig.averaging = (configList[4] == "Yes");
|
||||||
|
}
|
||||||
|
syncWithUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::setConfig(LF::Config config)
|
||||||
|
{
|
||||||
|
currConfig = config;
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
{
|
||||||
|
util->execCMDWithOutput(QString("lf config")
|
||||||
|
+ " q " + QString::number(currConfig.divisor)
|
||||||
|
+ " b " + QString::number(currConfig.bitPerSample)
|
||||||
|
+ " d " + QString::number(currConfig.decimation)
|
||||||
|
+ " a " + QString(currConfig.averaging ? "1" : "0")
|
||||||
|
+ " t " + QString::number(currConfig.triggerThreshold)
|
||||||
|
+ " s " + QString::number(currConfig.samplesToSkip),
|
||||||
|
500);
|
||||||
|
util->execCMDWithOutput("hw setlfdivisor " + QString::number(currConfig.divisor), 500);
|
||||||
|
}
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
{
|
||||||
|
util->execCMDWithOutput(QString("lf config")
|
||||||
|
+ " -a " + QString(currConfig.averaging ? "1" : "0")
|
||||||
|
+ " -b " + QString::number(currConfig.bitPerSample)
|
||||||
|
+ " --dec " + QString::number(currConfig.decimation)
|
||||||
|
+ " --divisor " + QString::number(currConfig.divisor)
|
||||||
|
+ " -s " + QString::number(currConfig.samplesToSkip)
|
||||||
|
+ " -t " + QString::number(currConfig.triggerThreshold),
|
||||||
|
500);
|
||||||
|
util->execCMDWithOutput("hw setlfdivisor -d " + QString::number(currConfig.divisor), 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::resetConfig()
|
||||||
|
{
|
||||||
|
setConfig(defaultConfig);
|
||||||
|
getConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
float LF::divisor2Freq(uint8_t divisor)
|
||||||
|
{
|
||||||
|
return (12000.0 / (divisor + 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t LF::freq2Divisor(float freq)
|
||||||
|
{
|
||||||
|
return ((uint16_t)(12000.0 / freq + 0.5) - 1); // uint16_t for (divisor + 1) = 256
|
||||||
|
}
|
||||||
|
|
||||||
|
void LF::syncWithUI()
|
||||||
|
{
|
||||||
|
ui->LF_Conf_freqDivisorBox->setValue(currConfig.divisor); // will trigger valueChanged()
|
||||||
|
ui->LF_Conf_bitPerSampleBox->setValue(currConfig.bitPerSample);
|
||||||
|
ui->LF_Conf_decimationBox->setValue(currConfig.decimation);
|
||||||
|
ui->LF_Conf_averagingBox->setChecked(currConfig.averaging);
|
||||||
|
ui->LF_Conf_thresholdBox->setValue(currConfig.triggerThreshold);
|
||||||
|
ui->LF_Conf_skipsBox->setValue(currConfig.samplesToSkip);
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#ifndef LF_H
|
||||||
|
#define LF_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
class LF : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LF(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
struct Config
|
||||||
|
{
|
||||||
|
uint8_t divisor;
|
||||||
|
uint8_t bitPerSample;
|
||||||
|
uint8_t decimation;
|
||||||
|
bool averaging;
|
||||||
|
uint8_t triggerThreshold;
|
||||||
|
uint16_t samplesToSkip;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr Config defaultConfig =
|
||||||
|
{
|
||||||
|
95,
|
||||||
|
8,
|
||||||
|
1,
|
||||||
|
true,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
void read();
|
||||||
|
void sniff();
|
||||||
|
void search();
|
||||||
|
void tune();
|
||||||
|
void getConfig();
|
||||||
|
void setConfig(LF::Config config);
|
||||||
|
void resetConfig();
|
||||||
|
static float divisor2Freq(uint8_t divisor);
|
||||||
|
static uint8_t freq2Divisor(float freq);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget* parent;
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
Util* util;
|
||||||
|
Config currConfig;
|
||||||
|
QRegularExpression* configPattern;
|
||||||
|
void syncWithUI();
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LF_H
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
#ifndef MIFARE_H
|
||||||
|
#define MIFARE_H
|
||||||
|
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
#include "ui/mf_attack_hardnesteddialog.h"
|
||||||
|
#include "ui/mf_uid_parameterdialog.h"
|
||||||
|
#include "ui/mf_sim_simdialog.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QMessageBox>
|
||||||
|
class Mifare : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
enum KeyType
|
||||||
|
{
|
||||||
|
KEY_A = 'A',
|
||||||
|
KEY_B = 'B',
|
||||||
|
};
|
||||||
|
|
||||||
|
enum DataType
|
||||||
|
{
|
||||||
|
DATA_INVALID,
|
||||||
|
DATA_WITHSPACE,
|
||||||
|
DATA_NOSPACE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CardType
|
||||||
|
{
|
||||||
|
quint8 type;
|
||||||
|
quint8 sector_size;
|
||||||
|
quint16 block_size;
|
||||||
|
quint8 blk[40];
|
||||||
|
quint8 blks[40];
|
||||||
|
QString typeText;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AccessType
|
||||||
|
{
|
||||||
|
ACC_NEVER = 0,
|
||||||
|
ACC_KEY_A = 1,
|
||||||
|
ACC_KEY_B = 2,
|
||||||
|
ACC_KEY_AB = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TargetType
|
||||||
|
{
|
||||||
|
TARGET_MIFARE,
|
||||||
|
TARGET_UID,
|
||||||
|
TARGET_EMULATOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const CardType card_mini;
|
||||||
|
static const CardType card_1k;
|
||||||
|
static const CardType card_2k;
|
||||||
|
static const CardType card_4k;
|
||||||
|
|
||||||
|
static const AccessType dataCondition[8][4];
|
||||||
|
static const AccessType trailerReadCondition[8][3];
|
||||||
|
static const AccessType trailerWriteCondition[8][3];
|
||||||
|
|
||||||
|
QString info(bool isRequiringOutput = false);
|
||||||
|
void chk();
|
||||||
|
void nested();
|
||||||
|
void darkside();
|
||||||
|
void hardnested();
|
||||||
|
void sniff();
|
||||||
|
void sniff14a();
|
||||||
|
void list();
|
||||||
|
void readOne(TargetType targetType = TARGET_MIFARE);
|
||||||
|
void readSelected(TargetType targetType = TARGET_MIFARE);
|
||||||
|
void writeOne(TargetType targetType = TARGET_MIFARE);
|
||||||
|
void writeSelected(TargetType targetType = TARGET_MIFARE);
|
||||||
|
void dump();
|
||||||
|
void restore();
|
||||||
|
|
||||||
|
void data_clearData(bool clearAll = true);
|
||||||
|
void data_clearKey(bool clearAll = true);
|
||||||
|
static bool data_isKeyValid(const QString& key);
|
||||||
|
static Mifare::DataType data_isDataValid(const QString& data);
|
||||||
|
void data_syncWithDataWidget(bool syncAll = true, int block = 0);
|
||||||
|
void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, KeyType keyType = KEY_A);
|
||||||
|
|
||||||
|
CardType cardType;
|
||||||
|
Mifare::CardType getCardType();
|
||||||
|
void setCardType(int type);
|
||||||
|
void wipeC();
|
||||||
|
void setParameterC();
|
||||||
|
|
||||||
|
bool data_loadDataFile(const QString& filename);
|
||||||
|
bool data_loadKeyFile(const QString& filename);
|
||||||
|
bool data_saveDataFile(const QString& filename, bool isBin);
|
||||||
|
bool data_saveKeyFile(const QString& filename, bool isBin);
|
||||||
|
void data_key2Data();
|
||||||
|
void data_data2Key();
|
||||||
|
|
||||||
|
void data_setData(int block, const QString& data);
|
||||||
|
void data_setKey(int sector, KeyType keyType, const QString& key);
|
||||||
|
void lockC();
|
||||||
|
void wipeE();
|
||||||
|
void simulate();
|
||||||
|
void loadSniff(const QString& file);
|
||||||
|
void saveSniff(const QString& file);
|
||||||
|
void data_fillKeys();
|
||||||
|
|
||||||
|
static QList<quint8> data_getACBits(const QString& text);
|
||||||
|
static int data_b2s(int block);
|
||||||
|
static bool data_isACBitsValid(const QString& text, QList<quint8> *returnHalfBytes = nullptr);
|
||||||
|
QString data_getUID();
|
||||||
|
quint16 getTrailerBlockId(quint8 sectorId, qint8 cardTypeId = -1); // -1: use current cardtype
|
||||||
|
public slots:
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget* parent;
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
Util* util;
|
||||||
|
|
||||||
|
QStringList* keyAList;
|
||||||
|
QStringList* keyBList;
|
||||||
|
QStringList* dataList;
|
||||||
|
QRegularExpression* dataPattern;
|
||||||
|
QRegularExpression* keyPattern_res;
|
||||||
|
QRegularExpression* keyPattern;
|
||||||
|
QString bin2text(const QByteArray& buff, int start, int length);
|
||||||
|
|
||||||
|
QString _readblk(int blockId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
|
||||||
|
QStringList _readsec(int sectorId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
|
||||||
|
bool _writeblk(int blockId, KeyType keyType, const QString& key, const QString& data, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MIFARE_H
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#include "pm3process.h"
|
|
||||||
|
|
||||||
PM3Process::PM3Process(QObject* parent): QProcess(parent)
|
|
||||||
{
|
|
||||||
setProcessChannelMode(PM3Process::MergedChannels);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList PM3Process::findPort()
|
|
||||||
{
|
|
||||||
QSerialPort serial;
|
|
||||||
QStringList retList;
|
|
||||||
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
|
|
||||||
{
|
|
||||||
serial.setPort(info);
|
|
||||||
if(serial.open(QIODevice::ReadWrite))
|
|
||||||
{
|
|
||||||
retList<<info.portName();
|
|
||||||
serial.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return retList;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PM3Process::start(const QString path, const QString port)
|
|
||||||
{
|
|
||||||
// using "-f" option to make the client output flushed after every print.
|
|
||||||
QProcess::start(path, QStringList()<<port<<"-f",QProcess::Unbuffered|QProcess::ReadWrite);
|
|
||||||
return waitForStarted();
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#ifndef PM3PROCESS_H
|
|
||||||
#define PM3PROCESS_H
|
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QString>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QtSerialPort/QSerialPortInfo>
|
|
||||||
#include <QtSerialPort/QSerialPort>
|
|
||||||
|
|
||||||
class PM3Process : public QProcess
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PM3Process(QObject* parent=nullptr);
|
|
||||||
bool start(const QString path, const QString port);
|
|
||||||
QStringList findPort();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // PM3PROCESS_H
|
|
||||||
@@ -0,0 +1,263 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QListWidgetItem>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFontDialog>
|
||||||
|
#include <QtSerialPort/QSerialPortInfo>
|
||||||
|
#include <QtSerialPort/QSerialPort>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QSizePolicy>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
#include "common/myeventfilter.h"
|
||||||
|
#include "common/pm3process.h"
|
||||||
|
#include "module/mifare.h"
|
||||||
|
#include "module/lf.h"
|
||||||
|
#include "common/util.h"
|
||||||
|
#include "ui/mf_trailerdecoderdialog.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MainWindow(QWidget *parent = nullptr);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
void initUI();
|
||||||
|
bool eventFilter(QObject *watched, QEvent *event);
|
||||||
|
public slots:
|
||||||
|
void refreshOutput(const QString& output);
|
||||||
|
void refreshCMD(const QString& cmd);
|
||||||
|
void setStatusBar(QLabel* target, const QString& text);
|
||||||
|
void onPM3StateChanged(bool st, const QString& info);
|
||||||
|
void MF_onMFCardTypeChanged(int id, bool st);
|
||||||
|
void on_Raw_keyPressed(QObject *obj_addr, QEvent &event);
|
||||||
|
void on_MF_keyWidget_resized(QObject *obj_addr, QEvent &event);
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void on_PM3_connectButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_sendCMDButton_clicked();
|
||||||
|
|
||||||
|
void on_PM3_disconnectButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_clearOutputButton_clicked();
|
||||||
|
|
||||||
|
void sendMSG();
|
||||||
|
|
||||||
|
void on_portSearchTimer_timeout();
|
||||||
|
|
||||||
|
void on_Raw_CMDHistoryBox_stateChanged(int arg1);
|
||||||
|
|
||||||
|
void on_Raw_clearHistoryButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_CMDHistoryWidget_itemDoubleClicked(QListWidgetItem *item);
|
||||||
|
|
||||||
|
void on_MF_Attack_chkButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Attack_nestedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Attack_hardnestedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sniff_sniffButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sniff_listButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_readSelectedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_readBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_writeBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Attack_infoButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_writeSelectedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_dumpButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_RW_restoreButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_readSelectedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_readBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_writeSelectedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_writeBlockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_File_loadButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_File_saveButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_data2KeyButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_key2DataButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_dataWidget_itemChanged(QTableWidgetItem *item);
|
||||||
|
|
||||||
|
void on_MF_File_clearButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_keyWidget_itemChanged(QTableWidgetItem *item);
|
||||||
|
|
||||||
|
void on_MF_fontButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_wipeButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_aboutUIDButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_setParaButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_UID_lockButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sim_readSelectedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sim_writeSelectedButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sim_clearButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sim_simButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sniff_loadButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_Sniff_saveButton_clicked();
|
||||||
|
|
||||||
|
void on_GroupBox_clicked(bool checked);
|
||||||
|
|
||||||
|
void on_MF_selectAllBox_stateChanged(int arg1);
|
||||||
|
|
||||||
|
void on_MF_fillKeysButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_14aSniff_snoopButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_trailerDecoderButton_clicked();
|
||||||
|
|
||||||
|
void on_MF_selectTrailerBox_stateChanged(int arg1);
|
||||||
|
|
||||||
|
void on_stopButton_clicked();
|
||||||
|
|
||||||
|
void on_Raw_CMDEdit_textChanged(const QString &arg1);
|
||||||
|
|
||||||
|
void on_MF_Attack_darksideButton_clicked();
|
||||||
|
|
||||||
|
void on_Set_Client_startArgsEdit_editingFinished();
|
||||||
|
|
||||||
|
void on_Set_Client_forceEnabledBox_stateChanged(int arg1);
|
||||||
|
|
||||||
|
void on_Set_GUI_setLanguageButton_clicked();
|
||||||
|
|
||||||
|
void setButtonsEnabled(bool st);
|
||||||
|
|
||||||
|
void on_PM3_refreshPortButton_clicked();
|
||||||
|
|
||||||
|
void on_Set_Client_envScriptEdit_editingFinished();
|
||||||
|
|
||||||
|
void on_Set_Client_saveWorkingDirButton_clicked();
|
||||||
|
|
||||||
|
void on_Set_Client_keepClientActiveBox_stateChanged(int arg1);
|
||||||
|
|
||||||
|
void on_LF_Conf_freqSlider_valueChanged(int value);
|
||||||
|
|
||||||
|
void on_LF_Conf_freqDivisorBox_valueChanged(int arg1);
|
||||||
|
|
||||||
|
void on_LF_Conf_freq125kButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Conf_freq134kButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Op_searchButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Op_readButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Op_tuneButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Op_sniffButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Conf_getButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Conf_setButton_clicked();
|
||||||
|
|
||||||
|
void on_LF_Conf_resetButton_clicked();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MainWindow* ui;
|
||||||
|
QButtonGroup* MFCardTypeBtnGroup;
|
||||||
|
QLabel* connectStatusBar;
|
||||||
|
QLabel* programStatusBar;
|
||||||
|
QLabel* PM3VersionBar;
|
||||||
|
QPushButton* stopButton;
|
||||||
|
QAction* dockAllWindows;
|
||||||
|
QAction* myInfo;
|
||||||
|
QAction* currVersion;
|
||||||
|
QAction* checkUpdate;
|
||||||
|
QSettings* settings;
|
||||||
|
MyEventFilter* keyEventFilter;
|
||||||
|
MyEventFilter* resizeEventFilter;
|
||||||
|
|
||||||
|
QString stashedCMDEditText;
|
||||||
|
int stashedIndex = -1;
|
||||||
|
|
||||||
|
void uiInit();
|
||||||
|
|
||||||
|
PM3Process* pm3;
|
||||||
|
bool pm3state;
|
||||||
|
bool keepButtonsEnabled;
|
||||||
|
bool keepClientActive;
|
||||||
|
QThread* pm3Thread;
|
||||||
|
QTimer* portSearchTimer;
|
||||||
|
QStringList portList;
|
||||||
|
QStringList clientEnv;
|
||||||
|
QDir* clientWorkingDir;
|
||||||
|
|
||||||
|
Mifare* mifare;
|
||||||
|
LF* lf;
|
||||||
|
Util* util;
|
||||||
|
|
||||||
|
QList<QDockWidget*> dockList;
|
||||||
|
QMenu* contextMenu;
|
||||||
|
|
||||||
|
MF_trailerDecoderDialog* decDialog;
|
||||||
|
|
||||||
|
void signalInit();
|
||||||
|
void MF_widgetReset();
|
||||||
|
void setTableItem(QTableWidget *widget, int row, int column, const QString& text);
|
||||||
|
void setState(bool st);
|
||||||
|
void saveClientPath(const QString& path);
|
||||||
|
void onLFfreqConfChanged(int value, bool isCustomized);
|
||||||
|
void dockInit();
|
||||||
|
protected:
|
||||||
|
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||||
|
signals:
|
||||||
|
void connectPM3(const QString& path, const QStringList args);
|
||||||
|
void reconnectPM3();
|
||||||
|
void killPM3();
|
||||||
|
void setSerialListener(bool state);
|
||||||
|
void setSerialListener(const QString& name, bool state);
|
||||||
|
void setProcEnv(const QStringList *env);
|
||||||
|
void setWorkingDir(const QString& dir);
|
||||||
|
};
|
||||||
|
#endif // MAINWINDOW_H
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#include "mf_attack_hardnesteddialog.h"
|
||||||
|
#include "ui_mf_attack_hardnesteddialog.h"
|
||||||
|
|
||||||
|
MF_Attack_hardnestedDialog::MF_Attack_hardnestedDialog(int blocks, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::MF_Attack_hardnestedDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
for(int i = 0; i < blocks; i++)
|
||||||
|
{
|
||||||
|
ui->knownKeySectorBox->addItem(QString::number(i));
|
||||||
|
ui->targetKeySectorBox->addItem(QString::number(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MF_Attack_hardnestedDialog::~MF_Attack_hardnestedDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_Attack_hardnestedDialog::on_buttonBox_accepted()
|
||||||
|
{
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
emit sendCMD("hf mf hardnested "
|
||||||
|
+ ui->knownKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyTypeBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyBox->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeyTypeBox->currentText());
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
|
||||||
|
emit sendCMD("hf mf hardnested "
|
||||||
|
+ ui->knownKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyTypeBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->knownKeyBox->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeySectorBox->currentText()
|
||||||
|
+ " "
|
||||||
|
+ ui->targetKeyTypeBox->currentText());
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef MF_ATTACK_HARDNESTEDDIALOG_H
|
||||||
|
#define MF_ATTACK_HARDNESTEDDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class MF_Attack_hardnestedDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MF_Attack_hardnestedDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MF_Attack_hardnestedDialog(int blocks, QWidget *parent = nullptr);
|
||||||
|
~MF_Attack_hardnestedDialog();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MF_Attack_hardnestedDialog *ui;
|
||||||
|
signals:
|
||||||
|
void sendCMD(const QString& cmd);
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_accepted();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MF_ATTACK_HARDNESTEDDIALOG_H
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MF_Attack_hardnestedDialog</class>
|
||||||
|
<widget class="QDialog" name="MF_Attack_hardnestedDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>287</width>
|
||||||
|
<height>173</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Hardnested Attack</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Known Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="knownKeySectorBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="knownKeyTypeBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>A</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>B</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="knownKeyBox">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Courier</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">FFFFFFFFFFFF</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Target Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Block:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="targetKeySectorBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>60</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="targetKeyTypeBox">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>A</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>B</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>31</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>MF_Attack_hardnestedDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>MF_Attack_hardnestedDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
#include "mf_sim_simdialog.h"
|
||||||
|
#include "ui_mf_sim_simdialog.h"
|
||||||
|
|
||||||
|
MF_Sim_simDialog::MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::MF_Sim_simDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
{
|
||||||
|
ui->atqaGroupBox->setVisible(false);
|
||||||
|
ui->atqaLine->setVisible(false);
|
||||||
|
ui->sakGroupBox->setVisible(false);
|
||||||
|
ui->sakLine->setVisible(false);
|
||||||
|
ui->vGroupBox->setVisible(false);
|
||||||
|
ui->vLine->setVisible(false);
|
||||||
|
}
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
{
|
||||||
|
ui->fGroupBox->setVisible(false);
|
||||||
|
ui->fLine->setVisible(false);
|
||||||
|
ui->rGroupBox->setVisible(false);
|
||||||
|
ui->rLine->setVisible(false);
|
||||||
|
ui->uBox->setText("-u");
|
||||||
|
ui->nBox->setText("-n");
|
||||||
|
ui->iBox->setText("-i");
|
||||||
|
ui->xBox->setText("--crack");
|
||||||
|
ui->eBox->setText("-e");
|
||||||
|
}
|
||||||
|
this->cardType = cardType;
|
||||||
|
this->cardTypeText = cardTypeText;
|
||||||
|
}
|
||||||
|
|
||||||
|
MF_Sim_simDialog::~MF_Sim_simDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_Sim_simDialog::on_eBox_clicked(bool checked)
|
||||||
|
{
|
||||||
|
if(checked)
|
||||||
|
{
|
||||||
|
ui->iBox->setChecked(true);
|
||||||
|
ui->xBox->setChecked(true);
|
||||||
|
}
|
||||||
|
if(!ui->eBox->isChecked() && !ui->fBox->isChecked())
|
||||||
|
{
|
||||||
|
ui->iBox->setEnabled(true);
|
||||||
|
ui->xBox->setEnabled(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->iBox->setEnabled(false);
|
||||||
|
ui->xBox->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_Sim_simDialog::on_fBox_clicked(bool checked)
|
||||||
|
{
|
||||||
|
if(checked)
|
||||||
|
{
|
||||||
|
ui->iBox->setChecked(true);
|
||||||
|
ui->xBox->setChecked(true);
|
||||||
|
}
|
||||||
|
if(!ui->eBox->isChecked() && !ui->fBox->isChecked())
|
||||||
|
{
|
||||||
|
ui->iBox->setEnabled(true);
|
||||||
|
ui->xBox->setEnabled(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->iBox->setEnabled(false);
|
||||||
|
ui->xBox->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_Sim_simDialog::on_buttonBox_accepted()
|
||||||
|
{
|
||||||
|
QString paras;
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
{
|
||||||
|
paras += (ui->uBox->isChecked() ? "u " + ui->uEdit->text() + " " : "");
|
||||||
|
paras += (ui->nBox->isChecked() ? "n " + ui->nEdit->text() + " " : "");
|
||||||
|
paras += (ui->iBox->isChecked() ? "i " : "");
|
||||||
|
paras += (ui->xBox->isChecked() ? "x " : "");
|
||||||
|
paras += (ui->eBox->isChecked() ? "e " : "");
|
||||||
|
paras += (ui->fBox->isChecked() ? "f " + ui->fEdit->text() + " " : "");
|
||||||
|
paras += (ui->rBox->isChecked() ? "r " : "");
|
||||||
|
emit sendCMD(QString("hf mf sim ") + "*" + QString::number(cardType) + " " + paras.trimmed());
|
||||||
|
}
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
|
||||||
|
{
|
||||||
|
paras += (ui->uBox->isChecked() ? "-u " + ui->uEdit->text() + " " : "");
|
||||||
|
paras += (ui->atqaBox->isChecked() ? "--atqa " + ui->atqaEdit->text() + " " : "");
|
||||||
|
paras += (ui->sakBox->isChecked() ? "--sak " + ui->sakEdit->text() + " " : "");
|
||||||
|
paras += (ui->nBox->isChecked() ? "-n " + ui->nEdit->text() + " " : "");
|
||||||
|
paras += (ui->iBox->isChecked() ? "-i " : "");
|
||||||
|
paras += (ui->xBox->isChecked() ? "--crack " : "");
|
||||||
|
paras += (ui->eBox->isChecked() ? "-e " : "");
|
||||||
|
paras += (ui->vBox->isChecked() ? "-v " : "");
|
||||||
|
emit sendCMD(QString("hf mf sim --") + cardTypeText + " " + paras.trimmed());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef MF_SIM_SIMDIALOG_H
|
||||||
|
#define MF_SIM_SIMDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QDebug>
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class MF_Sim_simDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MF_Sim_simDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent = nullptr);
|
||||||
|
~MF_Sim_simDialog();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_eBox_clicked(bool checked);
|
||||||
|
|
||||||
|
void on_fBox_clicked(bool checked);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MF_Sim_simDialog *ui;
|
||||||
|
int cardType;
|
||||||
|
QString cardTypeText;
|
||||||
|
signals:
|
||||||
|
void sendCMD(const QString& cmd);
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_accepted();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MF_SIM_SIMDIALOG_H
|
||||||
@@ -0,0 +1,667 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MF_Sim_simDialog</class>
|
||||||
|
<widget class="QDialog" name="MF_Sim_simDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>461</width>
|
||||||
|
<height>524</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Simulate</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="uGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="uLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="uBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>u</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="uEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="uLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="atqaGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="atqaLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="atqaBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>--atqa</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="atqaEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Provide explicit ATQA (2 bytes)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="atqaLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="sakGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="sakLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="sakBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>--sak</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="sakEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Provide explicit SAK (1 byte)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="sakLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="nGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="nLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="nBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>n</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="nEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="nLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="iGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="iLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="iBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>i</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Interactive, means that console will not be returned until simulation finishes or is aborted</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="iLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="xGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="xLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="xBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>x</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="xLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="eGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="eLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="eBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>e</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>set keys found from 'reader attack' to emulator memory (implies x(--crack) and i)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="eLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="fGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="fLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="fBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>f</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="fEdit">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>get UIDs to use for 'reader attack' from file 'f <filename.txt>' (implies x and i)</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="fLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="rGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="rLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="rBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>r</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="rLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="vGroupBox">
|
||||||
|
<layout class="QHBoxLayout" name="vLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="vBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>-v</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>verbose output</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="vLine">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>MF_Sim_simDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>MF_Sim_simDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
#include "mf_trailerdecoderdialog.h"
|
||||||
|
#include "ui_mf_trailerdecoderdialog.h"
|
||||||
|
|
||||||
|
MF_trailerDecoderDialog::MF_trailerDecoderDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::MF_trailerDecoderDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
QRegularExpression re("(([0-9a-fA-F]{2} ){0,4})|([0-9a-fA-F]{0,8})");
|
||||||
|
validator = new QRegularExpressionValidator(this);
|
||||||
|
validator->setRegularExpression(re);
|
||||||
|
ui->accessBitsEdit->setValidator(validator);
|
||||||
|
|
||||||
|
sizeGroup = new QButtonGroup(this);
|
||||||
|
sizeGroup->addButton(ui->size4Button, 4);
|
||||||
|
sizeGroup->addButton(ui->size16Button, 16);
|
||||||
|
connect(sizeGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MF_trailerDecoderDialog::on_blockSizeChanged);
|
||||||
|
connect(ui->C0Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||||
|
connect(ui->C1Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||||
|
connect(ui->C2Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||||
|
connect(ui->C3Box, QOverload<int>::of(&QSpinBox::valueChanged), this, &MF_trailerDecoderDialog::on_boxChanged);
|
||||||
|
|
||||||
|
ui->dataBlockWidget->setRowCount(3);
|
||||||
|
ui->dataBlockWidget->setColumnCount(4);
|
||||||
|
ui->trailerBlockWidget->setRowCount(2);
|
||||||
|
ui->trailerBlockWidget->setColumnCount(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
MF_trailerDecoderDialog::~MF_trailerDecoderDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
void MF_trailerDecoderDialog::on_accessBitsEdit_textChanged(const QString &arg1)
|
||||||
|
{
|
||||||
|
ui->C0Box->blockSignals(true);
|
||||||
|
ui->C1Box->blockSignals(true);
|
||||||
|
ui->C2Box->blockSignals(true);
|
||||||
|
ui->C3Box->blockSignals(true);
|
||||||
|
QList<quint8> ACBits = Mifare::data_getACBits(arg1);
|
||||||
|
if(ACBits.size() == 0)
|
||||||
|
{
|
||||||
|
ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(200, 0, 0)");
|
||||||
|
ui->isAccessBitsValidLabel->setText(tr("Invalid!\nIt could make the whole sector blocked irreversibly!"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->C0Box->setValue(ACBits[0]);
|
||||||
|
ui->C1Box->setValue(ACBits[1]);
|
||||||
|
ui->C2Box->setValue(ACBits[2]);
|
||||||
|
ui->C3Box->setValue(ACBits[3]);
|
||||||
|
ui->isAccessBitsValidLabel->setStyleSheet("color:rgb(0, 200, 0)");
|
||||||
|
ui->isAccessBitsValidLabel->setText(tr("Valid"));
|
||||||
|
bool isKeyBReadable = ACBits[3] == 0 || ACBits[3] == 1 || ACBits[3] == 4;
|
||||||
|
for(int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
setTableItem(ui->trailerBlockWidget, 0, j, Mifare::trailerReadCondition[ACBits[3]][j]);
|
||||||
|
setTableItem(ui->trailerBlockWidget, 1, j, Mifare::trailerWriteCondition[ACBits[3]][j]);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
for(int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
Mifare::AccessType type = Mifare::dataCondition[ACBits[i]][j];
|
||||||
|
if(type == Mifare::ACC_KEY_B && isKeyBReadable)
|
||||||
|
{
|
||||||
|
type = Mifare::ACC_NEVER;
|
||||||
|
}
|
||||||
|
else if(type == Mifare::ACC_KEY_AB && isKeyBReadable)
|
||||||
|
{
|
||||||
|
type = Mifare::ACC_KEY_A;
|
||||||
|
}
|
||||||
|
setTableItem(ui->dataBlockWidget, i, j, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->C0Box->blockSignals(false);
|
||||||
|
ui->C1Box->blockSignals(false);
|
||||||
|
ui->C2Box->blockSignals(false);
|
||||||
|
ui->C3Box->blockSignals(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_trailerDecoderDialog::on_blockSizeChanged(int id, bool st)
|
||||||
|
{
|
||||||
|
if(st)
|
||||||
|
{
|
||||||
|
if(id == 4)
|
||||||
|
{
|
||||||
|
ui->dataBlockWidget->verticalHeaderItem(0)->setText("Block0");
|
||||||
|
ui->dataBlockWidget->verticalHeaderItem(1)->setText("Block1");
|
||||||
|
ui->dataBlockWidget->verticalHeaderItem(2)->setText("Block2");
|
||||||
|
}
|
||||||
|
else if(id == 16)
|
||||||
|
{
|
||||||
|
ui->dataBlockWidget->verticalHeaderItem(0)->setText("Block0~4");
|
||||||
|
ui->dataBlockWidget->verticalHeaderItem(1)->setText("Block5~9");
|
||||||
|
ui->dataBlockWidget->verticalHeaderItem(2)->setText("Block10~14");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_trailerDecoderDialog::setTableItem(QTableWidget* widget, int row, int column, Mifare::AccessType accessType)
|
||||||
|
{
|
||||||
|
if(widget->item(row, column) == nullptr)
|
||||||
|
widget->setItem(row, column, new QTableWidgetItem());
|
||||||
|
QString text;
|
||||||
|
if(accessType == Mifare::ACC_NEVER)
|
||||||
|
{
|
||||||
|
text = "X";
|
||||||
|
}
|
||||||
|
else if(accessType == Mifare::ACC_KEY_A)
|
||||||
|
{
|
||||||
|
text = "KeyA";
|
||||||
|
}
|
||||||
|
else if(accessType == Mifare::ACC_KEY_B)
|
||||||
|
{
|
||||||
|
text = "KeyB";
|
||||||
|
}
|
||||||
|
else if(accessType == Mifare::ACC_KEY_AB)
|
||||||
|
{
|
||||||
|
text = "KeyA+B";
|
||||||
|
}
|
||||||
|
widget->item(row, column)->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_trailerDecoderDialog::on_boxChanged()
|
||||||
|
{
|
||||||
|
quint8 ACBits[4];
|
||||||
|
ACBits[0] = ui->C0Box->value();
|
||||||
|
ACBits[1] = ui->C1Box->value();
|
||||||
|
ACBits[2] = ui->C2Box->value();
|
||||||
|
ACBits[3] = ui->C3Box->value();
|
||||||
|
quint8 halfBytes[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
for(int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
halfBytes[2] |= (((ACBits[i] >> 0) & 1) << i);
|
||||||
|
halfBytes[5] |= (((ACBits[i] >> 1) & 1) << i);
|
||||||
|
halfBytes[4] |= (((ACBits[i] >> 2) & 1) << i);
|
||||||
|
}
|
||||||
|
halfBytes[0] = (~halfBytes[5]) & 0xf;
|
||||||
|
halfBytes[1] = (~halfBytes[2]) & 0xf;
|
||||||
|
halfBytes[3] = (~halfBytes[4]) & 0xf;
|
||||||
|
|
||||||
|
QString result;
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
result += QString::number(halfBytes[i * 2], 16);
|
||||||
|
result += QString::number(halfBytes[i * 2 + 1], 16);
|
||||||
|
result += " ";
|
||||||
|
}
|
||||||
|
result = result.toUpper();
|
||||||
|
ui->accessBitsEdit->setText(result);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef MF_TRAILERDECODERDIALOG_H
|
||||||
|
#define MF_TRAILERDECODERDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QValidator>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include "../module/mifare.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class MF_trailerDecoderDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MF_trailerDecoderDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MF_trailerDecoderDialog(QWidget *parent = nullptr);
|
||||||
|
~MF_trailerDecoderDialog();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void on_accessBitsEdit_textChanged(const QString& arg1);
|
||||||
|
|
||||||
|
void on_blockSizeChanged(int id, bool st);
|
||||||
|
|
||||||
|
void on_boxChanged();
|
||||||
|
private:
|
||||||
|
Ui::MF_trailerDecoderDialog *ui;
|
||||||
|
QRegularExpressionValidator* validator;
|
||||||
|
QButtonGroup* sizeGroup;
|
||||||
|
void setTableItem(QTableWidget *widget, int row, int column, Mifare::AccessType accessType);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MF_TRAILERDECODERDIALOG_H
|
||||||
@@ -0,0 +1,402 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MF_trailerDecoderDialog</class>
|
||||||
|
<widget class="QDialog" name="MF_trailerDecoderDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>534</width>
|
||||||
|
<height>507</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Trailer Decoder</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="sizeGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Blocks</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="size4Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>4</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="size16Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>16</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Trailer Data:
|
||||||
|
(like "FF0780" or "FF 07 80")</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="accessBitsEdit"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="isAccessBitsValidLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Or set bits manually</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cx0</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="C0Box">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cx1</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="C1Box">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cx2</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="C2Box">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cx3</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="C3Box">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Data Block Permission:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTableWidget" name="dataBlockWidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>4</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<row>
|
||||||
|
<property name="text">
|
||||||
|
<string>Block0</string>
|
||||||
|
</property>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<property name="text">
|
||||||
|
<string>Block1</string>
|
||||||
|
</property>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<property name="text">
|
||||||
|
<string>Block2</string>
|
||||||
|
</property>
|
||||||
|
</row>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Read</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Write</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Increase</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Decrease/Transfer/Restore</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Trailer Block Permission:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTableWidget" name="trailerBlockWidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>3</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<row>
|
||||||
|
<property name="text">
|
||||||
|
<string>Read</string>
|
||||||
|
</property>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<property name="text">
|
||||||
|
<string>Write</string>
|
||||||
|
</property>
|
||||||
|
</row>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>KeyA</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Access Bits</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>KeyB</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reference:
|
||||||
|
MF1S70YYX_V1 Product data sheet
|
||||||
|
Rev. 3.2 — 23 November 2017</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Note:the Access Bits usually contains 4 bytes(8 hex symbols), but only the first 3 bytes matters. You can set the 4th byte randomly.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>MF_trailerDecoderDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>MF_trailerDecoderDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#include "mf_uid_parameterdialog.h"
|
||||||
|
#include "ui_mf_uid_parameterdialog.h"
|
||||||
|
|
||||||
|
MF_UID_parameterDialog::MF_UID_parameterDialog(const QString& uid, const QString& atqa, const QString& sak, QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::MF_UID_parameterDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->UIDLineEdit->setText(uid);
|
||||||
|
ui->ATQALineEdit->setText(atqa);
|
||||||
|
ui->SAKLineEdit->setText(sak);
|
||||||
|
}
|
||||||
|
|
||||||
|
MF_UID_parameterDialog::~MF_UID_parameterDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MF_UID_parameterDialog::on_buttonBox_accepted()
|
||||||
|
{
|
||||||
|
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
|
||||||
|
emit sendCMD("hf mf csetuid "
|
||||||
|
+ ui->UIDLineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->ATQALineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->SAKLineEdit->text());
|
||||||
|
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
|
||||||
|
emit sendCMD("hf mf csetuid "
|
||||||
|
+ ui->UIDLineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->ATQALineEdit->text()
|
||||||
|
+ " "
|
||||||
|
+ ui->SAKLineEdit->text());
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef MF_UID_PARAMETERDIALOG_H
|
||||||
|
#define MF_UID_PARAMETERDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include "common/util.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class MF_UID_parameterDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MF_UID_parameterDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MF_UID_parameterDialog(const QString& uid, const QString& atqa, const QString& sak, QWidget *parent = nullptr);
|
||||||
|
~MF_UID_parameterDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::MF_UID_parameterDialog *ui;
|
||||||
|
signals:
|
||||||
|
void sendCMD(const QString& cmd);
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_accepted();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MF_UID_PARAMETERDIALOG_H
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MF_UID_parameterDialog</class>
|
||||||
|
<widget class="QDialog" name="MF_UID_parameterDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>205</width>
|
||||||
|
<height>186</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Set Parameter</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="uIDLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>UID:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="UIDLineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="ATQALabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>ATQA:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="ATQALineEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="SAKLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>SAK:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="SAKLineEdit"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>MF_UID_parameterDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>MF_UID_parameterDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||