63 Commits

Author SHA1 Message Date
wh201906 aa6b93984c A small patch
Support specifying client working directory
Clean all compile warnings
2021-02-17 01:26:14 +08:00
wh201906 7f96c061dc Merge pull request #14 from wh201906/dev
V0.1.4
2021-02-16 14:28:50 +08:00
wh201906 b8c4e8e339 V0.1.4 2021-02-16 14:25:20 +08:00
wh201906 4f10e3d75c All functions are compatible to Iceman/RRG fork
Use different foreground color for Trailer block and Block 0
2021-02-16 13:52:04 +08:00
wh201906 63f3424871 Support wipe(), lockUFUID(), setUIDParameter(),
in latest Iceman repo
Fix a error in keyPattern
Test all R/W functions in Iceman client and Official client
2021-02-16 01:17:50 +08:00
wh201906 24a6e1869b Support hardnested(), darkside(), readblk(),
readsec() in latest Iceman repo
2021-02-15 23:46:05 +08:00
wh201906 6baa09221e Support chk(), nested() in latest Iceman repo 2021-02-15 23:00:02 +08:00
wh201906 6e5f654cc5 Support running a external script before client start,
to configure the environment variables

Optimize stop(reconnect) logic
Search valid ports automatically
Update translations
2021-02-15 18:38:34 +08:00
wh201906 83445c7eef Add new features
Support change language in Settings
Support customized start arguments
Strech data section in MF_dataWidget and key section in MF_keyWidget
2021-02-14 22:47:56 +08:00
wh201906 5330ed8d14 Some changes
Refactor execCMDWithOutput
Add UI for advanced settings
Add stop button(reconnect)
Update translations
2021-02-13 23:58:11 +08:00
wh201906 a56a503b23 Some slight changes
Add HighDPI support(not tested)
Support Mifare darkside attack
Hide unfinished function tabs
2021-02-12 23:48:25 +08:00
wh201906 77d8049738 Merge pull request #13 from wh201906/master
Replace textChanged() with valueChanged(). This fixes #9
2020-11-04 15:12:39 +08:00
wh201906 bf9b3fb076 Merge branch 'dev' into master 2020-11-04 15:12:18 +08:00
wh201906 6d3dd5056c Replace textChanged() with valueChanged(). This fixes #9 2020-11-04 15:09:28 +08:00
wh201906 e687cc39fd Merge pull request #12 from wh201906/master
Update translation
2020-11-01 22:46:33 +08:00
wh201906 3c3944d150 Slight change 2020-11-01 22:43:46 +08:00
wh201906 091b4f63d1 Merge pull request #11 from ruling/master
Update zh_CN.ts
2020-11-01 18:17:56 +08:00
wh201906 0c4220c9a5 Change some translation 2020-10-31 18:19:06 +08:00
Ruling 986e9aacfe Correct some Chinese Translation
Correct some Chinese Translation
2020-10-30 12:58:11 +08:00
Ruling ce262db52c Update zh_CN.ts 2020-10-27 11:31:33 +08:00
wh201906 73533608e6 Add some useless UI 2020-08-14 00:46:07 +08:00
wh201906 2f38d3c8c5 Support choose history command by Key_Up and Key_Down 2020-08-13 16:39:04 +08:00
wh201906 f2d00ee088 Replace QString with const QString& 2020-08-13 09:30:47 +08:00
wh201906 862f0775f8 Shorten the waitTime for execCMDWithOutput() 2020-08-12 12:30:15 +08:00
wh201906 a7985c5c89 Stop the running command after disconnected 2020-08-11 11:51:27 +08:00
wh201906 a3e6aa787b Check Access Bits when writing to selected blocks 2020-08-11 11:30:33 +08:00
wh201906 1c273a6527 Update preview for Trailer Decoder 2020-08-10 10:37:09 +08:00
wh201906 3f899845b7 Update README 2020-08-09 11:16:45 +08:00
wh201906 475580c342 Merge pull request #5 from wh201906/dev
V0.1.3
2020-08-09 10:34:54 +08:00
wh201906 3a577bdd32 V0.1.3 2020-08-09 10:33:15 +08:00
wh201906 f8d2bbb206 Fix Trailer Decoder and add write feedback 2020-08-09 10:32:48 +08:00
wh201906 d6beafe175 Merge pull request #4 from wh201906/dev
V0.1.2
2020-08-08 22:02:32 +08:00
wh201906 f881a05fa3 V0.1.2 2020-08-08 22:00:16 +08:00
wh201906 ad10a6e789 Support Choose Trailer block 2020-08-08 21:49:43 +08:00
wh201906 bf8136a7fe Unify all read and write functions 2020-08-08 21:04:09 +08:00
wh201906 6af85bffc0 Remove writeC() and readC(), unify them into _readblk() and _writeblk() 2020-08-08 17:41:08 +08:00
wh201906 3751349004 Update Introducton 2020-08-08 16:51:34 +08:00
wh201906 44c61a8202 Update translation 2020-08-08 12:10:44 +08:00
wh201906 fbe8a5e51d Fix a small bug 2020-08-08 11:23:17 +08:00
wh201906 41bbcd2c4a Support write selected blocks and fix a bug 2020-08-08 00:19:37 +08:00
wh201906 4dba7882e5 Support read selected blocks 2020-08-07 23:51:24 +08:00
wh201906 25d7886f2a Refactor _readsec() and readAll() 2020-08-07 17:30:48 +08:00
wh201906 7e4dedeff1 Save client path automatically 2020-08-07 15:28:17 +08:00
wh201906 7dfabb60e9 Support encode Access Bits(in the Trailer Decoder) 2020-08-06 14:53:49 +08:00
wh201906 46b3912e82 Refactor 2020-08-06 11:19:56 +08:00
wh201906 fe8f8b2d51 Refactor _readblk() and _readsec() 2020-08-06 00:38:44 +08:00
wh201906 d15b8e21fc Iceman support: info(), chk(), nested() 2020-08-05 23:55:14 +08:00
wh201906 eb5fa7ec9a Replace QRegExp with QRegularExpression(Uncompleted) 2020-08-05 22:46:41 +08:00
wh201906 ef6ebea568 Support Iceman fork(Command Line only) 2020-08-05 19:08:02 +08:00
wh201906 6f860111df Complete Trailer Decoder(without test) 2020-08-05 00:45:54 +08:00
wh201906 a935ff9703 Add Trailer Decoder(Uncompleted) 2020-08-04 23:33:14 +08:00
wh201906 02b0c312a4 Rename something 2020-08-04 16:05:21 +08:00
wh201906 946d0acb01 Refactor and Add _readsec() 2020-08-04 13:44:20 +08:00
wh201906 a60b28ee66 Add Fill keys 2020-08-01 22:04:30 +08:00
wh201906 43752bd5e4 Small fix 2020-08-01 21:48:59 +08:00
wh201906 a77985824c Add _readblk() (not tested) 2020-08-01 21:30:55 +08:00
wh201906 cd122b8959 Refactor(Replace isKeyA with KeyType) 2020-07-29 22:02:49 +08:00
wh201906 87dddf4d3d Add block selection 2020-06-27 14:02:58 +08:00
wh201906 b2baaede5d Unfinished 2020-06-26 23:48:08 +08:00
wh201906 7ea9c363fd Fix a small bug 2020-06-26 22:39:46 +08:00
wh201906 241b0cdc29 Optimize writeAll() 2020-06-26 22:35:39 +08:00
wh201906 3181848e75 Make UI customizable 2020-06-13 01:27:59 +08:00
wh201906 5cccb7b8bb Merge pull request #3 from wh201906/dev
V0.1.1
2020-05-09 23:54:59 +08:00
44 changed files with 5250 additions and 1671 deletions
-1
View File
@@ -14,7 +14,6 @@
*.so.* *.so.*
*_pch.h.cpp *_pch.h.cpp
*_resource.rc *_resource.rc
*.qm
.#* .#*
*.*# *.*#
core core
+6 -1
View File
@@ -16,25 +16,30 @@ DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \ SOURCES += \
common/myeventfilter.cpp \
main.cpp \ main.cpp \
common/pm3process.cpp \ common/pm3process.cpp \
common/util.cpp \ common/util.cpp \
module/mifare.cpp \ module/mifare.cpp \
ui/mf_trailerdecoderdialog.cpp \
ui/mf_sim_simdialog.cpp \ ui/mf_sim_simdialog.cpp \
ui/mf_uid_parameterdialog.cpp \ ui/mf_uid_parameterdialog.cpp \
ui/mainwindow.cpp \ ui/mainwindow.cpp \
ui/mf_attack_hardnesteddialog.cpp \ ui/mf_attack_hardnesteddialog.cpp \
HEADERS += \ HEADERS += \
common/myeventfilter.h \
common/pm3process.h \ common/pm3process.h \
common/util.h \ common/util.h \
module/mifare.h \ module/mifare.h \
ui/mf_trailerdecoderdialog.h \
ui/mf_sim_simdialog.h \ ui/mf_sim_simdialog.h \
ui/mf_uid_parameterdialog.h \ ui/mf_uid_parameterdialog.h \
ui/mainwindow.h \ ui/mainwindow.h \
ui/mf_attack_hardnesteddialog.h \ ui/mf_attack_hardnesteddialog.h \
FORMS += \ FORMS += \
ui/mf_trailerdecoderdialog.ui \
ui/mf_sim_simdialog.ui \ ui/mf_sim_simdialog.ui \
ui/mf_uid_parameterdialog.ui \ ui/mf_uid_parameterdialog.ui \
ui/mainwindow.ui \ ui/mainwindow.ui \
@@ -49,7 +54,7 @@ qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target
VERSION = 0.1.1 VERSION = 0.1.4
QMAKE_TARGET_PRODUCT = "Proxmark3GUI" QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI" QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
QMAKE_TARGET_COMPANY = "wh201906" QMAKE_TARGET_COMPANY = "wh201906"
+71 -11
View File
@@ -1,33 +1,93 @@
# Proxmark3GUI # Proxmark3GUI
A GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client ![downloads](https://img.shields.io/github/downloads/wh201906/Proxmark3GUI/total)
[中文](README/README.zh_CN.md) A cross-platform GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client
[中文](README/doc/README_zh_CN.md)
*** ***
## Features ## Features
+ Support raw commands of Proxmark3 client + Easy to find available Serial Port
+ Support raw commands of Proxmark3 client(Official/Iceman)
+ Have a friendly UI to test Mifare cards + Have a friendly UI to test Mifare cards
+ Easy to edit Mifare data files + Support different card size(MINI, 1K, 2K, 4K)
+ Support binary(.bin .dump) files and text(.eml) files + Easy to edit Mifare block data
+ ... + Easy to read all/selected blocks with well-designed read logic
+ Easy to write all/selected blocks
+ Support binary(.bin .dump) files and text(.eml) files
+ Analyze Access Bits
+ Support Chinese Magic Card
+ Customize UI
+ ...
*** ***
## Previews ## Preview
![nested_attack](README/mf_nested_attack.gif) ![preview](README/img/preview.png)
![mf_load_file](README/mf_load_file.gif) [more previews](README/doc/previews.md)
![mf_edit_file](README/mf_edit_file.gif) ***
![raw_command](README/raw_command.gif) ## About Iceman fork/repo
The [Iceman fork/repo](https://github.com/RfidResearchGroup/proxmark3) has more powerful functions like offline sniff. These guys even developed a new hardware called Proxmark3 RDV4 with smart card support. But the official repo and the Iceman repo is not fully compatible.
This GUI is compatible with Iceman/RRG repo(tested on v4.9237)
***
## About Compiled Windows clients
A cool guy [Gator96100](https://github.com/Gator96100) creates [ProxSpace](https://github.com/Gator96100/ProxSpace) and makes it possible to compile both the firmware and client on Windows.
Also, he makes the [pre-compiled Windows client](https://www.proxmarkbuilds.org/) so you can download it and run your PM3 client on Windows instantly.
I included his compiled client in my releases so you can use the GUI on the fly, and you can also use the GUI with your prefered client.
Great thanks to him.
***
## Build on Linux
cd ~
git clone https://github.com/wh201906/Proxmark3GUI.git
cd Proxmark3GUI
mkdir build
cd build
qmake ../
make
make clean
cp -r ../lang ./
./Proxmark3GUI
*** ***
## Update Log: ## Update Log:
### V0.1.4
+ Optimize performance
+ Optimize UI
+ Search available ports automatically
+ Add High-DPI support
+ Support configuring environment variables by script
(Useful when the client requires specific environment variables)
+ All functions are compatible with Iceman/RRG repo(tested on v4.9237)
+ Support specifying client working directory
+ Fix some bugs
### V0.1.3
+ Fix Trailer Decoder
+ Add feedback when writing selected blocks
### V0.1.2
+ Optimize read logic
+ Make UI Customizable
+ Save client path automatically
+ Add Trailer Decoder(Deprecated, plz use V0.1.3 or higher version)
+ Support read/write selected blocks
+ Support a few Iceman functions
+ Fix some bugs
### V0.1.1 ### V0.1.1
+ Complete Mifare module(support simulate and sniff) + Complete Mifare module(support simulate and sniff)
-38
View File
@@ -1,38 +0,0 @@
# Proxmark3GUI
一个自制的[Proxmark3](https://github.com/Proxmark/proxmark3) GUI
[English](../README.md)
***
## 特色功能
+ 支持直接输入PM3命令
+ 有针对于Mifare卡(IC卡)的图形界面
+ 支持编辑Mifare扇区数据文件
+ 可以打开二进制/文本格式的扇区数据文件
+ ...
***
## 预览图
![nested_attack](mf_nested_attack.gif)
![mf_load_file](mf_load_file.gif)
![mf_edit_file](mf_edit_file.gif)
![raw_command](raw_command.gif)
***
## 更新日志:
### V0.1.1
+ 完成整个Mifare模块(支持模拟卡和嗅探功能)
### V0.1
+ 支持处理Mifare卡片及相关数据文件
### V0.0.1
+ 一个带串口选择框的实验版本
+97
View File
@@ -0,0 +1,97 @@
# Proxmark3GUI
![downloads](https://img.shields.io/github/downloads/wh201906/Proxmark3GUI/total)
一个自制的[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界面
+ ...
***
## 预览图
![preview](../img/preview_zh_CN.png)
[更多预览](../doc/previews.md)
***
## 关于冰人版
[冰人版](https://github.com/RfidResearchGroup/proxmark3)(Iceman/RRG)的客户端和固件更新更为激进,相比官方版具有更多的功能
此GUI所有功能均兼容冰人版(在v4.9237上测试通过)
***
## 关于预编译Windows客户端
一位国外大佬 [Gator96100](https://github.com/Gator96100) 做了个 [ProxSpace](https://github.com/Gator96100/ProxSpace) 以便在Windows平台上编译PM3固件和客户端,他还把自己编译好的客户端放到了[网站](https://www.proxmarkbuilds.org/)上
release页面中有含客户端的GUI。这个GUI也可以搭配你自己的客户端使用
(本来打算在CSDN下载里面放几个最新版客户端的,结果不能把下载币改为0)
感谢大佬
***
## 在Linux系统下编译
cd ~
git clone https://github.com/wh201906/Proxmark3GUI.git
cd Proxmark3GUI
mkdir build
cd build
qmake ../
make
make clean
cp -r ../lang ./
./Proxmark3GUI
***
## 更新日志:
### V0.1.4
+ 优化性能
+ 优化用户界面
+ 自动搜索可用端口
+ 支持高分屏
+ 可通过外部脚本配置环境变量
(在客户端需要配置环境变量时很有用)
+ 全功能兼容冰人版(在v4.9237上测试通过)
+ 支持指定客户端工作路径
+ 修复部分bug
### V0.1.3
+ 修复访问控制位解码器
+ 写多个块时显示写入结果
### V0.1.2
+ 优化读卡逻辑
+ UI自定义
+ 自动保存客户端路径
+ 添加访问控制位解码器(也可用于自己构造访问控制位)(有bug,请使用V0.1.3或更高版本)
+ 支持仅读写选中块
+ 支持部分冰人功能
+ 修复部分bug
### V0.1.1
+ 完成整个Mifare模块(支持模拟卡和嗅探功能)
### V0.1
+ 支持处理Mifare卡片及相关数据文件
### V0.0.1
+ 一个带串口选择框的实验版本
+16
View File
@@ -0,0 +1,16 @@
## Previews
Raw Command:
![raw_command](../img/raw_command.gif)
Mifare Nested Attack:
![nested_attack](../img/mf_nested_attack.gif)
Mifare Load File:
![mf_loadfile](../img/mf_loadfile.gif)
Mifare Edit File:
![mf_editfile](../img/mf_editfile.gif)
Mifare Trailer Decoder:
![mf_trailer](../img/mf_trailer.gif)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 797 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 637 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 857 KiB

+13
View File
@@ -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);
}
+22
View File
@@ -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
+51 -7
View File
@@ -14,31 +14,63 @@ PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent)
connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead); connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead);
} }
void PM3Process::connectPM3(const QString path, const QString port) void PM3Process::connectPM3(const QString& path, const QString& port, const QStringList args)
{ {
QString result;
Util::ClientType clientType;
setRequiringOutput(true); setRequiringOutput(true);
// stash for reconnect
currPath = path;
currPort = port;
currArgs = args;
// using "-f" option to make the client output flushed after every print. // using "-f" option to make the client output flushed after every print.
start(path, QStringList() << port << "-f", QProcess::Unbuffered | QProcess::ReadWrite); start(path, args, QProcess::Unbuffered | QProcess::ReadWrite);
if(waitForStarted(10000)) if(waitForStarted(10000))
{ {
while(waitForReadyRead(1000)) waitForReadyRead(10000);
;
setRequiringOutput(false); setRequiringOutput(false);
QString result = *requiredOutput; result = *requiredOutput;
if(result.indexOf("[=]") != -1)
{
clientType = Util::CLIENTTYPE_ICEMAN;
setRequiringOutput(true);
write("hw version\r\n");
for(int i = 0; i < 10; i++)
{
waitForReadyRead(200);
result += *requiredOutput;
}
setRequiringOutput(false);
}
else
{
clientType = Util::CLIENTTYPE_OFFICIAL;
}
if(result.indexOf("os: ") != -1) // make sure the PM3 is connected if(result.indexOf("os: ") != -1) // make sure the PM3 is connected
{ {
emit changeClientType(clientType);
result = result.mid(result.indexOf("os: ")); result = result.mid(result.indexOf("os: "));
result = result.left(result.indexOf("\r\n")); result = result.left(result.indexOf("\r\n"));
result = result.mid(3, result.lastIndexOf(" ") - 3); result = result.mid(3, result.lastIndexOf(" ") - 3);
emit PM3StatedChanged(true, result); emit PM3StatedChanged(true, result);
setSerialListener(port, true);
// if the arguments don't contain <port>, then disable the port listener
// useful when using offline sniff
if(args.indexOf(port) != -1)
setSerialListener(port, true);
} }
else else
kill(); kill();
} }
} }
void PM3Process::reconnectPM3()
{
connectPM3(currPath, currPort, currArgs);
}
void PM3Process::setRequiringOutput(bool st) void PM3Process::setRequiringOutput(bool st)
{ {
isRequiringOutput = st; isRequiringOutput = st;
@@ -82,7 +114,6 @@ void PM3Process::testThread()
qDebug() << "PM3:" << QThread::currentThread(); qDebug() << "PM3:" << QThread::currentThread();
} }
qint64 PM3Process::write(QString data) qint64 PM3Process::write(QString data)
{ {
return QProcess::write(data.toLatin1()); return QProcess::write(data.toLatin1());
@@ -100,3 +131,16 @@ void PM3Process::onReadyRead()
} }
} }
void PM3Process::setProcEnv(const QStringList* env)
{
// qDebug() << "passed Env List" << *env;
this->setEnvironment(*env);
// qDebug() << "final Env List" << processEnvironment().toStringList();
}
void PM3Process::setWorkingDir(const QString& dir)
{
// the working directory cannot be the default, or the client will failed to load the dll
this->setWorkingDirectory(dir);
}
+16 -4
View File
@@ -8,6 +8,10 @@
#include <QTimer> #include <QTimer>
#include <QtSerialPort/QSerialPortInfo> #include <QtSerialPort/QSerialPortInfo>
#include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPort>
#include <QProcessEnvironment>
#include <QDir>
#include "util.h"
class PM3Process : public QProcess class PM3Process : public QProcess
{ {
@@ -19,9 +23,12 @@ public:
void testThread(); void testThread();
public slots: public slots:
void connectPM3(const QString path, const QString port); void connectPM3(const QString& path, const QString& port, const QStringList args);
void setSerialListener(const QString &name, bool state); void setSerialListener(const QString& name, bool state);
qint64 write(QString data); qint64 write(QString data);
void reconnectPM3();
void setProcEnv(const QStringList* env);
void setWorkingDir(const QString& dir);
private slots: private slots:
void onTimeout(); void onTimeout();
void onReadyRead(); void onReadyRead();
@@ -31,9 +38,14 @@ private:
void setRequiringOutput(bool st);// It only works in this class now void setRequiringOutput(bool st);// It only works in this class now
QTimer* serialListener; QTimer* serialListener;
QSerialPortInfo* portInfo; QSerialPortInfo* portInfo;
QString currPath;
QString currPort;
QStringList currArgs;
signals: signals:
void PM3StatedChanged(bool st, QString info = ""); void PM3StatedChanged(bool st, const QString& info = "");
void newOutput(QString output); void newOutput(const QString& output);
void changeClientType(Util::ClientType);
}; };
#endif // PM3PROCESS_H #endif // PM3PROCESS_H
+81 -11
View File
@@ -1,13 +1,16 @@
#include "util.h" #include "util.h"
Util::ClientType Util::clientType = CLIENTTYPE_OFFICIAL;
Util::Util(QObject *parent) : QObject(parent) Util::Util(QObject *parent) : QObject(parent)
{ {
isRequiringOutput = false; isRequiringOutput = false;
requiredOutput = new QString(); requiredOutput = new QString();
timeStamp = QTime::currentTime(); timeStamp = QTime::currentTime();
qRegisterMetaType<Util::ClientType>("Util::ClientType");
} }
void Util::processOutput(QString output) void Util::processOutput(const QString& output)
{ {
// qDebug() << "Util::processOutput:" << output; // qDebug() << "Util::processOutput:" << output;
if(isRequiringOutput) if(isRequiringOutput)
@@ -18,35 +21,102 @@ void Util::processOutput(QString output)
emit refreshOutput(output); emit refreshOutput(output);
} }
void Util::execCMD(QString cmd) void Util::execCMD(const QString& cmd)
{ {
qDebug() << cmd; qDebug() << "executing: " << cmd;
emit write(cmd + "\r\n"); if(isRunning)
emit write(cmd + "\r\n");
} }
QString Util::execCMDWithOutput(QString cmd, unsigned long timeout) QString Util::execCMDWithOutput(const QString& cmd, ReturnTrigger trigger)
{ {
// if the trigger is empty, this function will wait trigger.waitTime then return all outputs during the wait time.
// otherwise, this function will return empty string if no trigger is detected, or return outputs if any trigger is detected.
// the waitTime will be refreshed if the client have new outputs
bool isResultFound = false;
QRegularExpression re;
re.setPatternOptions(QRegularExpression::DotMatchesEverythingOption);
if(!isRunning)
return "";
QTime currTime = QTime::currentTime(); QTime currTime = QTime::currentTime();
QTime targetTime = QTime::currentTime().addMSecs(timeout); QTime targetTime = QTime::currentTime().addMSecs(trigger.waitTime);
isRequiringOutput = true; isRequiringOutput = true;
requiredOutput->clear(); requiredOutput->clear();
execCMD(cmd); execCMD(cmd);
while( QTime::currentTime() < targetTime) while(QTime::currentTime() < targetTime)
{ {
if(!isRunning)
break;
QApplication::processEvents(); QApplication::processEvents();
if(timeStamp > currTime) // qDebug() << "currOutput:" << *requiredOutput;
for(QString otpt : trigger.expectedOutputs)
{
re.setPattern(otpt);
isResultFound = re.match(*requiredOutput).hasMatch();
if(isResultFound)
{
qDebug() << "output Matched: " << *requiredOutput;
break;
}
}
if(isResultFound)
{
delay(200);
break;
}
if(timeStamp > currTime) //has new output
{ {
currTime = timeStamp; currTime = timeStamp;
targetTime = timeStamp.addMSecs(timeout); targetTime = timeStamp.addMSecs(trigger.waitTime);
} }
} }
isRequiringOutput = false; isRequiringOutput = false;
return *requiredOutput; return (isResultFound || trigger.expectedOutputs.isEmpty() ? *requiredOutput : "");
} }
void Util::delay(unsigned int msec) void Util::delay(unsigned int msec)
{ {
QTime timer = QTime::currentTime().addMSecs(msec); QTime timer = QTime::currentTime().addMSecs(msec);
while( QTime::currentTime() < timer ) while(QTime::currentTime() < timer)
QApplication::processEvents(QEventLoop::AllEvents, 100); QApplication::processEvents(QEventLoop::AllEvents, 100);
} }
Util::ClientType Util::getClientType()
{
return Util::clientType;
}
void Util::setClientType(Util::ClientType clientType)
{
Util::clientType = clientType;
}
void Util::setRunningState(bool st)
{
this->isRunning = st;
}
bool Util::chooseLanguage(QSettings* guiSettings, QMainWindow* window)
{
// make sure the GUISettings is not in any group
QSettings* langSettings = new QSettings("lang/languages.ini", QSettings::IniFormat);
QMap<QString, QString> langMap;
langSettings->setIniCodec("UTF-8");
langSettings->beginGroup("Languages");
QStringList langList = langSettings->allKeys();
for(int i = 0; i < langList.size(); i++)
langMap.insert(langSettings->value(langList[i]).toString(), langList[i]);
langSettings->endGroup();
delete langSettings;
bool isOk = false;
QString selectedText = QInputDialog::getItem(window, "", "Choose a language:", langMap.keys(), 0, false, &isOk);
if(isOk)
{
guiSettings->beginGroup("lang");
guiSettings->setValue("language", langMap[selectedText]);
guiSettings->endGroup();
guiSettings->sync();
}
return isOk;
}
+45 -4
View File
@@ -8,26 +8,67 @@
#include <QApplication> #include <QApplication>
#include <QTime> #include <QTime>
#include <QTimer> #include <QTimer>
#include <QMetaType>
#include <QRegularExpression>
#include <QSettings>
#include <QMainWindow>
#include <QInputDialog>
class Util : public QObject class Util : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
enum ClientType
{
CLIENTTYPE_OFFICIAL,
CLIENTTYPE_ICEMAN,
};
struct ReturnTrigger
{
unsigned long waitTime;
QStringList expectedOutputs;
ReturnTrigger(unsigned long time)
{
waitTime = time;
expectedOutputs = QStringList();
}
ReturnTrigger(const QStringList& outputs)
{
waitTime = 10000;
expectedOutputs = outputs;
}
ReturnTrigger(unsigned long time, const QStringList& outputs)
{
waitTime = time;
expectedOutputs = outputs;
}
};
Q_ENUM(Util::ClientType)
explicit Util(QObject *parent = nullptr); explicit Util(QObject *parent = nullptr);
void execCMD(QString cmd); void execCMD(const QString& cmd);
QString execCMDWithOutput(QString cmd, unsigned long timeout = 2000); QString execCMDWithOutput(const QString& cmd, ReturnTrigger trigger = 10000);
void delay(unsigned int msec); void delay(unsigned int msec);
static ClientType getClientType();
static const int rawTabIndex = 1;
static bool chooseLanguage(QSettings *guiSettings, QMainWindow *window);
public slots: public slots:
void processOutput(QString output); void processOutput(const QString& output);
static void setClientType(Util::ClientType clientType);
void setRunningState(bool st);
private: private:
bool isRequiringOutput; bool isRequiringOutput;
bool isRunning;
QString* requiredOutput; QString* requiredOutput;
QTime timeStamp; QTime timeStamp;
static ClientType clientType;
signals: signals:
void refreshOutput(const QString& output); void refreshOutput(const QString& output);
void write(QString data); void write(QString data); // connected to PM3Process::write(QString data);
}; };
#endif // UTIL_H #endif // UTIL_H
BIN
View File
Binary file not shown.
+623 -245
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
[Languages]
en_US=English
zh_CN=简体中文
BIN
View File
Binary file not shown.
+644 -304
View File
File diff suppressed because it is too large Load Diff
+25 -29
View File
@@ -4,54 +4,50 @@
#include <QSettings> #include <QSettings>
#include <QTranslator> #include <QTranslator>
#include <QMessageBox> #include <QMessageBox>
#include <QInputDialog> #include <QTextCodec>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QApplication a(argc, argv); QApplication a(argc, argv);
MainWindow w; MainWindow w;
QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat); QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
QVariant lang = settings->value("lang", "null"); settings->setIniCodec("UTF-8");
if(lang == "null") settings->beginGroup("lang");
QString currLang = settings->value("language", "").toString();
settings->endGroup();
if(currLang == "")
{ {
#ifdef Q_OS_WIN if(Util::chooseLanguage(settings, &w))
lang = "lang/en_US.qm";
#else
lang = "lang/en_US.ts";
#endif
QStringList langList;
langList.append("English");
langList.append("简体中文");
QString seletedText = QInputDialog::getItem(&w, "", "Choose a language:", langList, 0, false);
if(seletedText == "English")
{ {
#ifdef Q_OS_WIN settings->beginGroup("lang");
lang = "lang/en_US.qm"; currLang = settings->value("language", "").toString();
#else settings->endGroup();
lang = "lang/en_US.ts";
#endif
}
else if(seletedText == "简体中文")
{
#ifdef Q_OS_WIN
lang = "lang/zh_CN.qm";
#else
lang = "lang/zh_CN.ts";
#endif
} }
else
currLang = "en_US";
} }
currLang = "lang/" + currLang;
#ifdef Q_OS_WIN
currLang += ".qm";
#else
currLang += ".ts";;
#endif
QTranslator* translator = new QTranslator(&w); QTranslator* translator = new QTranslator(&w);
if(translator->load(lang.toString())) if(translator->load(currLang))
{ {
a.installTranslator(translator); a.installTranslator(translator);
settings->setValue("lang", lang);
} }
else else
{ {
QMessageBox::information(&w, "Error", "Can't load " + lang.toString() + " as translation file."); QMessageBox::information(&w, "Error", "Can't load " + currLang + " as translation file.");
} }
delete settings; delete settings;
w.initUI(); w.initUI();
w.show(); w.show();
return a.exec(); return a.exec();
} }
+842 -476
View File
File diff suppressed because it is too large Load Diff
+71 -69
View File
@@ -9,7 +9,7 @@
#include <QObject> #include <QObject>
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <QRegExp> #include <QRegularExpression>
#include <QMessageBox> #include <QMessageBox>
class Mifare : public QObject class Mifare : public QObject
{ {
@@ -17,18 +17,11 @@ class Mifare : public QObject
public: public:
explicit Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr); explicit Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent = nullptr);
QString info(bool isRequiringOutput = false); enum KeyType
void chk(); {
void nested(); KEY_A = 'A',
void hardnested(); KEY_B = 'B',
void sniff(); };
void list();
void read();
void readAll();
void write();
void writeAll();
void dump();
void restore();
enum DataType enum DataType
{ {
@@ -39,79 +32,85 @@ public:
struct CardType struct CardType
{ {
int type; quint8 type;
int sectors; quint8 sector_size;
int blocks; quint16 block_size;
int blk[40]; quint8 blk[40];
int blks[40]; quint8 blks[40];
QString typeText;
}; };
const CardType card_mini = enum AccessType
{ {
0, ACC_NEVER = 0,
5, ACC_KEY_A = 1,
20, ACC_KEY_B = 2,
{4, 4, 4, 4, 4}, ACC_KEY_AB = 3,
{0, 4, 8, 12, 16}
};
const CardType card_1k =
{
1,
16,
64,
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60}
};
const CardType card_2k =
{
2,
32,
128,
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124}
};
const CardType card_4k =
{
4,
40,
256,
{4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 16},
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 144, 160, 176, 192, 208, 224, 240}
}; };
void data_clearData(); enum TargetType
void data_clearKey(); {
bool data_isKeyValid(const QString &key); TARGET_MIFARE,
Mifare::DataType data_isDataValid(QString data); TARGET_UID,
TARGET_EMULATOR,
};
static const CardType card_mini;
static const CardType card_1k;
static const CardType card_2k;
static const CardType card_4k;
static const AccessType dataCondition[8][4];
static const AccessType trailerReadCondition[8][3];
static const AccessType trailerWriteCondition[8][3];
QString info(bool isRequiringOutput = false);
void chk();
void nested();
void darkside();
void hardnested();
void sniff();
void sniff14a();
void list();
void readOne(TargetType targetType = TARGET_MIFARE);
void readSelected(TargetType targetType = TARGET_MIFARE);
void writeOne(TargetType targetType = TARGET_MIFARE);
void writeSelected(TargetType targetType = TARGET_MIFARE);
void dump();
void restore();
void data_clearData(bool clearAll = true);
void data_clearKey(bool clearAll = true);
static bool data_isKeyValid(const QString& key);
static Mifare::DataType data_isDataValid(const QString& data);
void data_syncWithDataWidget(bool syncAll = true, int block = 0); void data_syncWithDataWidget(bool syncAll = true, int block = 0);
void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, bool isKeyA = true); void data_syncWithKeyWidget(bool syncAll = true, int sector = 0, KeyType keyType = KEY_A);
CardType cardType; CardType cardType;
Mifare::CardType getCardType(); Mifare::CardType getCardType();
void setCardType(int type); void setCardType(int type);
void writeAllC();
void writeC();
void readAllC();
void readC();
void wipeC(); void wipeC();
void setParameterC(); void setParameterC();
bool data_loadDataFile(const QString &filename); bool data_loadDataFile(const QString& filename);
bool data_loadKeyFile(const QString &filename); bool data_loadKeyFile(const QString& filename);
bool data_saveDataFile(const QString& filename, bool isBin); bool data_saveDataFile(const QString& filename, bool isBin);
bool data_saveKeyFile(const QString &filename, bool isBin); bool data_saveKeyFile(const QString& filename, bool isBin);
void data_key2Data(); void data_key2Data();
void data_data2Key(); void data_data2Key();
void data_setData(int block, const QString &data); void data_setData(int block, const QString& data);
void data_setKey(int sector, bool isKeyA, const QString &key); void data_setKey(int sector, KeyType keyType, const QString& key);
void lockC(); void lockC();
void writeAllE();
void readAllE();
void wipeE(); void wipeE();
void simulate(); void simulate();
void loadSniff(const QString& file); void loadSniff(const QString& file);
void saveSniff(const QString& file); void saveSniff(const QString& file);
void data_fillKeys();
static QList<quint8> data_getACBits(const QString& text);
static int data_b2s(int block);
static bool data_isACBitsValid(const QString& text, QList<quint8> *returnHalfBytes = nullptr);
public slots: public slots:
signals: signals:
@@ -123,11 +122,14 @@ private:
QStringList* keyAList; QStringList* keyAList;
QStringList* keyBList; QStringList* keyBList;
QStringList* dataList; QStringList* dataList;
QRegExp* dataPattern; QRegularExpression* dataPattern;
QRegExp* chkKeyPattern; QRegularExpression* keyPattern_res;
QRegExp* nestedKeyPattern; QRegularExpression* keyPattern;
QRegExp* UIDPattern; QString bin2text(const QByteArray& buff, int start, int length);
QString bin2text(const QByteArray &buff, int start, int length);
QString _readblk(int blockId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
QStringList _readsec(int sectorId, KeyType keyType, const QString& key, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
bool _writeblk(int blockId, KeyType keyType, const QString& key, const QString& data, TargetType targetType = TARGET_MIFARE, int waitTime = 300);
}; };
#endif // MIFARE_H #endif // MIFARE_H
+536 -79
View File
@@ -6,25 +6,45 @@ MainWindow::MainWindow(QWidget *parent):
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
{ {
ui->setupUi(this); ui->setupUi(this);
// ui->MF_simGroupBox->setVisible(false); // developing...
// ui->MF_sniffGroupBox->setVisible(false); // developing...
myInfo = new QAction("wh201906", this); myInfo = new QAction("wh201906", this);
currVersion = new QAction("Ver: " + QApplication::applicationVersion().section('.', 0, -2), this); // ignore the 4th version number
checkUpdate = new QAction(tr("Check Update"), this);
connect(myInfo, &QAction::triggered, [ = ]() connect(myInfo, &QAction::triggered, [ = ]()
{ {
QDesktopServices::openUrl(QUrl("https://github.com/wh201906")); QDesktopServices::openUrl(QUrl("https://github.com/wh201906"));
}); });
connect(checkUpdate, &QAction::triggered, [ = ]()
{
QDesktopServices::openUrl(QUrl("https://github.com/wh201906/Proxmark3GUI/releases"));
});
this->addAction(myInfo); this->addAction(myInfo);
this->addAction(currVersion);
this->addAction(checkUpdate);
settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
settings->setIniCodec("UTF-8");
pm3Thread = new QThread(this); pm3Thread = new QThread(this);
pm3 = new PM3Process(pm3Thread); pm3 = new PM3Process(pm3Thread);
// pm3->moveToThread(pm3Thread);
// pm3->init();
pm3Thread->start(); pm3Thread->start();
pm3state = false; pm3state = false;
clientWorkingDir = new QDir;
util = new Util(this); util = new Util(this);
mifare = new Mifare(ui, util, this); mifare = new Mifare(ui, util, this);
keyEventFilter = new MyEventFilter(QEvent::KeyRelease);
resizeEventFilter = new MyEventFilter(QEvent::Resize);
// hide unused tabs
ui->funcTab->removeTab(1);
ui->funcTab->removeTab(1);
portSearchTimer = new QTimer(this);
portSearchTimer->setInterval(2000);
connect(portSearchTimer, &QTimer::timeout, this, &MainWindow::on_portSearchTimer_timeout);
portSearchTimer->start();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@@ -47,62 +67,89 @@ void MainWindow::initUI() // will be called by main.app
// ******************** basic functions ******************** // ******************** basic functions ********************
void MainWindow::on_PM3_refreshPortButton_clicked() void MainWindow::on_portSearchTimer_timeout()
{ {
ui->PM3_portBox->clear(); QStringList newPortList;
QSerialPort serial;
QStringList serialList;
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{ {
qDebug() << info.isBusy() << info.isNull() << info.portName(); // qDebug() << info.isBusy() << info.isNull() << info.portName() << info.description();
serial.setPort(info); if(!info.isNull())
newPortList << info.portName();
if(serial.open(QIODevice::ReadWrite))
{
serialList << info.portName();
serial.close();
}
} }
foreach(QString port, serialList) if(newPortList != portList) // update PM3_portBox when available ports changed
{ {
ui->PM3_portBox->addItem(port); portList = newPortList;
ui->PM3_portBox->clear();
ui->PM3_portBox->addItems(portList);
} }
} }
void MainWindow::on_PM3_connectButton_clicked() void MainWindow::on_PM3_connectButton_clicked()
{ {
qDebug() << "Main:" << QThread::currentThread(); qDebug() << "Main:" << QThread::currentThread();
QString port = ui->PM3_portBox->currentText(); QString port = ui->PM3_portBox->currentText();
if(port == "") if(port == "")
QMessageBox::information(NULL, tr("Info"), tr("Plz choose a port first"), QMessageBox::Ok); QMessageBox::information(NULL, tr("Info"), tr("Plz choose a port first"), QMessageBox::Ok);
else else
{ {
emit connectPM3(ui->PM3_pathEdit->text(), port); QStringList args = ui->Set_Client_startArgsEdit->text().replace("<port>", port).split(' ');
saveClientPath(ui->PM3_pathEdit->text());
QProcess envSetProcess;
QFileInfo envScriptPath(ui->Set_Client_envScriptEdit->text());
if(envScriptPath.exists())
{
qDebug() << envScriptPath.absoluteFilePath();
#ifdef Q_OS_WIN
// cmd /c "<path>">>nul && set
envSetProcess.start("cmd /c \"" + envScriptPath.absoluteFilePath() + "\">>nul && set");
#else
// sh -c '. "<path>">>/dev/null && env'
envSetProcess.start("sh -c \' . \"" + envScriptPath.absoluteFilePath() + "\">>/dev/null && env");
#endif
envSetProcess.waitForReadyRead(10000);
clientEnv = QString(envSetProcess.readAll()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
// qDebug() << "Get Env List" << clientEnv;
}
else
clientEnv.clear();
emit setProcEnv(&clientEnv);
clientWorkingDir->setPath(QApplication::applicationDirPath());
qDebug() << clientWorkingDir->absolutePath();
clientWorkingDir->mkpath(ui->Set_Client_workingDirEdit->text());
qDebug() << clientWorkingDir->absolutePath();
clientWorkingDir->cd(ui->Set_Client_workingDirEdit->text());
qDebug() << clientWorkingDir->absolutePath();
emit setWorkingDir(clientWorkingDir->absolutePath());
emit connectPM3(ui->PM3_pathEdit->text(), port, args);
} }
} }
void MainWindow::onPM3StateChanged(bool st, QString info) void MainWindow::onPM3StateChanged(bool st, const QString& info)
{ {
pm3state = st; pm3state = st;
setState(st); setState(st);
if(st == true) if(st == true)
{ {
portSearchTimer->stop();
setStatusBar(PM3VersionBar, info); setStatusBar(PM3VersionBar, info);
setStatusBar(connectStatusBar, tr("Connected")); setStatusBar(connectStatusBar, tr("Connected"));
} }
else else
{ {
portSearchTimer->start();
setStatusBar(PM3VersionBar, "");
setStatusBar(connectStatusBar, tr("Not Connected")); setStatusBar(connectStatusBar, tr("Not Connected"));
} }
} }
void MainWindow::on_PM3_disconnectButton_clicked() void MainWindow::on_PM3_disconnectButton_clicked()
{ {
pm3state = false;
setState(false);
emit killPM3(); emit killPM3();
emit setSerialListener("", false); emit setSerialListener("", false);
setStatusBar(connectStatusBar, tr("Not Connected"));
} }
void MainWindow::refreshOutput(const QString& output) void MainWindow::refreshOutput(const QString& output)
@@ -112,17 +159,31 @@ void MainWindow::refreshOutput(const QString& output)
ui->Raw_outputEdit->moveCursor(QTextCursor::End); ui->Raw_outputEdit->moveCursor(QTextCursor::End);
} }
void MainWindow::refreshCMD(const QString& cmd) void MainWindow::on_stopButton_clicked()
{ {
ui->Raw_CMDEdit->setText(cmd); if(!pm3state)
if(cmd != "" && (ui->Raw_CMDHistoryWidget->count() == 0 || ui->Raw_CMDHistoryWidget->item(ui->Raw_CMDHistoryWidget->count() - 1)->text() != cmd)) on_PM3_disconnectButton_clicked();
ui->Raw_CMDHistoryWidget->addItem(cmd); else
{
on_PM3_disconnectButton_clicked();
for(int i = 0; i < 10; i++)
{
util->delay(200);
if(!pm3state)
break;
}
emit reconnectPM3();
}
} }
// ********************************************************* // *********************************************************
// ******************** raw command ******************** // ******************** raw command ********************
void MainWindow::on_Raw_CMDEdit_textChanged(const QString &arg1)
{
stashedCMDEditText = arg1;
}
void MainWindow::on_Raw_sendCMDButton_clicked() void MainWindow::on_Raw_sendCMDButton_clicked()
{ {
util->execCMD(ui->Raw_CMDEdit->text()); util->execCMD(ui->Raw_CMDEdit->text());
@@ -167,41 +228,184 @@ void MainWindow::sendMSG() // send command when pressing Enter
on_Raw_sendCMDButton_clicked(); on_Raw_sendCMDButton_clicked();
} }
void MainWindow::refreshCMD(const QString& cmd)
{
ui->Raw_CMDEdit->blockSignals(true);
ui->Raw_CMDEdit->setText(cmd);
if(cmd != "" && (ui->Raw_CMDHistoryWidget->count() == 0 || ui->Raw_CMDHistoryWidget->item(ui->Raw_CMDHistoryWidget->count() - 1)->text() != cmd))
ui->Raw_CMDHistoryWidget->addItem(cmd);
stashedCMDEditText = cmd;
stashedIndex = -1;
ui->Raw_CMDEdit->blockSignals(false);
}
void MainWindow::on_Raw_CMDEdit_keyPressed(QObject* obj_addr, QEvent& event)
{
if(obj_addr == ui->Raw_CMDEdit && event.type() == QEvent::KeyRelease)
{
QKeyEvent& keyEvent = static_cast<QKeyEvent&>(event);
if(keyEvent.key() == Qt::Key_Up)
{
if(stashedIndex > 0)
stashedIndex--;
else if(stashedIndex == -1)
stashedIndex = ui->Raw_CMDHistoryWidget->count() - 1;
}
else if(keyEvent.key() == Qt::Key_Down)
{
if(stashedIndex < ui->Raw_CMDHistoryWidget->count() - 1 && stashedIndex != -1)
stashedIndex++;
else if(stashedIndex == ui->Raw_CMDHistoryWidget->count() - 1)
stashedIndex = -1;
}
if(keyEvent.key() == Qt::Key_Up || keyEvent.key() == Qt::Key_Down)
{
ui->Raw_CMDEdit->blockSignals(true);
if(stashedIndex == -1)
ui->Raw_CMDEdit->setText(stashedCMDEditText);
else
ui->Raw_CMDEdit->setText(ui->Raw_CMDHistoryWidget->item(stashedIndex)->text());
ui->Raw_CMDEdit->blockSignals(false);
}
}
}
// ***************************************************** // *****************************************************
// ******************** mifare ******************** // ******************** mifare ********************
void MainWindow::MF_onTypeChanged(int id, bool st) void MainWindow::on_MF_keyWidget_resized(QObject* obj_addr, QEvent& event)
{ {
typeBtnGroup->blockSignals(true); if(obj_addr == ui->MF_keyWidget && event.type() == QEvent::Resize)
qDebug() << id << typeBtnGroup->checkedId(); {
QTableWidget* widget = (QTableWidget*)obj_addr;
int keyItemWidth = widget->width();
keyItemWidth -= widget->verticalScrollBar()->width();
keyItemWidth -= 2 * widget->frameWidth();
keyItemWidth -= widget->horizontalHeader()->sectionSize(0);
widget->horizontalHeader()->resizeSection(1, keyItemWidth / 2);
widget->horizontalHeader()->resizeSection(2, keyItemWidth / 2);
}
}
void MainWindow::MF_onMFCardTypeChanged(int id, bool st)
{
MFCardTypeBtnGroup->blockSignals(true);
qDebug() << id << MFCardTypeBtnGroup->checkedId();
if(!st) if(!st)
{ {
int result = QMessageBox::question(this, tr("Info"), tr("When Changeing card type, the data and keys in this app will be cleard.") + "\n" + tr("Continue?"), QMessageBox::Yes | QMessageBox::No); int result;
if(id > MFCardTypeBtnGroup->checkedId()) // id is specified in uiInit() with a proper order, so I can compare the size by id.
{
result = QMessageBox::question(this, tr("Info"), tr("Some of the data and key will be cleared.") + "\n" + tr("Continue?"), QMessageBox::Yes | QMessageBox::No);
}
else
{
result = QMessageBox::Yes;
}
if(result == QMessageBox::Yes) if(result == QMessageBox::Yes)
{ {
qDebug() << "Yes"; qDebug() << "Yes";
mifare->setCardType(typeBtnGroup->checkedId()); mifare->setCardType(MFCardTypeBtnGroup->checkedId());
MF_widgetReset(); MF_widgetReset();
mifare->data_syncWithDataWidget();
mifare->data_syncWithKeyWidget();
} }
else else
{ {
qDebug() << "No"; qDebug() << "No";
typeBtnGroup->button(id)->setChecked(true); MFCardTypeBtnGroup->button(id)->setChecked(true);
} }
} }
typeBtnGroup->blockSignals(false); MFCardTypeBtnGroup->blockSignals(false);
} }
void MainWindow::on_MF_data2KeyBotton_clicked() void MainWindow::on_MF_selectAllBox_stateChanged(int arg1)
{
ui->MF_dataWidget->blockSignals(true);
ui->MF_selectAllBox->blockSignals(true);
ui->MF_selectTrailerBox->blockSignals(true);
if(arg1 == Qt::PartiallyChecked)
{
ui->MF_selectAllBox->setTristate(false);
ui->MF_selectAllBox->setCheckState(Qt::Checked);
}
for(int i = 0; i < mifare->cardType.block_size; i++)
{
ui->MF_dataWidget->item(i, 1)->setCheckState(ui->MF_selectAllBox->checkState());
}
for(int i = 0; i < mifare->cardType.sector_size; i++)
{
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(ui->MF_selectAllBox->checkState());
}
ui->MF_selectTrailerBox->setCheckState(ui->MF_selectAllBox->checkState());
ui->MF_dataWidget->blockSignals(false);
ui->MF_selectAllBox->blockSignals(false);
ui->MF_selectTrailerBox->blockSignals(false);
}
void MainWindow::on_MF_selectTrailerBox_stateChanged(int arg1)
{
int selectedSubBlocks = 0;
ui->MF_dataWidget->blockSignals(true);
ui->MF_selectAllBox->blockSignals(true);
ui->MF_selectTrailerBox->blockSignals(true);
if(arg1 == Qt::PartiallyChecked)
{
ui->MF_selectTrailerBox->setTristate(false);
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
}
for(int i = 0; i < mifare->cardType.sector_size; i++)
{
ui->MF_dataWidget->item(mifare->cardType.blks[i] + mifare->cardType.blk[i] - 1, 1)->setCheckState(ui->MF_selectTrailerBox->checkState());
selectedSubBlocks = 0;
for(int j = 0; j < mifare->cardType.blk[i]; j++)
{
if(ui->MF_dataWidget->item(j + mifare->cardType.blks[i], 1)->checkState() == Qt::Checked)
selectedSubBlocks++;
}
if(selectedSubBlocks == 0)
{
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Unchecked);
}
else if(selectedSubBlocks == mifare->cardType.blk[i])
{
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Checked);
}
else
{
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::PartiallyChecked);
}
}
ui->MF_dataWidget->blockSignals(false);
ui->MF_selectAllBox->blockSignals(false);
ui->MF_selectTrailerBox->blockSignals(false);
}
void MainWindow::on_MF_data2KeyButton_clicked()
{ {
mifare->data_data2Key(); mifare->data_data2Key();
} }
void MainWindow::on_MF_key2DataBotton_clicked() void MainWindow::on_MF_key2DataButton_clicked()
{ {
mifare->data_key2Data(); mifare->data_key2Data();
} }
void MainWindow::on_MF_fillKeysButton_clicked()
{
mifare->data_fillKeys();
}
void MainWindow::on_MF_trailerDecoderButton_clicked()
{
decDialog = new MF_trailerDecoderDialog(this);
decDialog->show();
}
void MainWindow::on_MF_fontButton_clicked() void MainWindow::on_MF_fontButton_clicked()
{ {
bool isOK = false; bool isOK = false;
@@ -216,8 +420,100 @@ void MainWindow::on_MF_fontButton_clicked()
void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item) void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
{ {
ui->MF_dataWidget->blockSignals(true);
ui->MF_selectAllBox->blockSignals(true);
ui->MF_selectTrailerBox->blockSignals(true);
if(item->column() == 0)
{
int selectedSectors = 0;
for(int i = 0; i < mifare->cardType.blk[Mifare::data_b2s(item->row())]; i++)
{
ui->MF_dataWidget->item(i + item->row(), 1)->setCheckState(item->checkState());
qDebug() << i << mifare->cardType.blk[item->row()] << i + item->row() << ui->MF_dataWidget->item(i + item->row(), 1)->text();
}
for(int i = 0; i < mifare->cardType.sector_size; i++)
{
if(ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->checkState() == Qt::Checked)
{
selectedSectors++;
}
}
if(selectedSectors == 0)
{
ui->MF_selectAllBox->setCheckState(Qt::Unchecked);
ui->MF_selectTrailerBox->setCheckState(Qt::Unchecked);
}
else if(selectedSectors == mifare->cardType.sector_size)
{
ui->MF_selectAllBox->setCheckState(Qt::Checked);
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
}
else
{
ui->MF_selectAllBox->setCheckState(Qt::PartiallyChecked);
ui->MF_selectTrailerBox->setCheckState(Qt::PartiallyChecked);
}
}
else if(item->column() == 1)
{
int selectedSubBlocks = 0;
int selectedBlocks = 0;
int selectedTrailers = 0;
if(item->column() == 2) for(int i = 0; i < mifare->cardType.block_size; i++)
{
if(ui->MF_dataWidget->item(i, 1)->checkState() == Qt::Checked)
selectedBlocks++;
}
for(int i = 0; i < mifare->cardType.blk[Mifare::data_b2s(item->row())]; i++)
{
if(ui->MF_dataWidget->item(i + mifare->cardType.blks[Mifare::data_b2s(item->row())], 1)->checkState() == Qt::Checked)
selectedSubBlocks++;
}
for(int i = 0; i < mifare->cardType.sector_size; i++)
{
int targetBlock = mifare->cardType.blks[i] + mifare->cardType.blk[i] - 1;
if(ui->MF_dataWidget->item(targetBlock, 1)->checkState() == Qt::Checked)
selectedTrailers++;
}
if(selectedBlocks == 0)
{
ui->MF_selectAllBox->setCheckState(Qt::Unchecked);
}
else if(selectedBlocks == mifare->cardType.block_size)
{
ui->MF_selectAllBox->setCheckState(Qt::Checked);
}
else
{
ui->MF_selectAllBox->setCheckState(Qt::PartiallyChecked);
}
if(selectedSubBlocks == 0)
{
ui->MF_dataWidget->item(mifare->cardType.blks[Mifare::data_b2s(item->row())], 0)->setCheckState(Qt::Unchecked);
}
else if(selectedSubBlocks == mifare->cardType.blk[Mifare::data_b2s(item->row())])
{
ui->MF_dataWidget->item(mifare->cardType.blks[Mifare::data_b2s(item->row())], 0)->setCheckState(Qt::Checked);
}
else
{
ui->MF_dataWidget->item(mifare->cardType.blks[Mifare::data_b2s(item->row())], 0)->setCheckState(Qt::PartiallyChecked);
}
if(selectedTrailers == 0)
{
ui->MF_selectTrailerBox->setCheckState(Qt::Unchecked);
}
else if(selectedTrailers == mifare->cardType.sector_size)
{
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
}
else
{
ui->MF_selectTrailerBox->setCheckState(Qt::PartiallyChecked);
}
}
else if(item->column() == 2)
{ {
QString data = item->text().replace(" ", "").toUpper(); QString data = item->text().replace(" ", "").toUpper();
if(data == "" || mifare->data_isDataValid(data) == Mifare::DATA_NOSPACE) if(data == "" || mifare->data_isDataValid(data) == Mifare::DATA_NOSPACE)
@@ -230,6 +526,9 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
} }
mifare->data_syncWithDataWidget(false, item->row()); mifare->data_syncWithDataWidget(false, item->row());
} }
ui->MF_dataWidget->blockSignals(false);
ui->MF_selectAllBox->blockSignals(false);
ui->MF_selectTrailerBox->blockSignals(false);
} }
void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item) void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item)
@@ -239,26 +538,26 @@ void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item)
QString key = item->text().replace(" ", "").toUpper(); QString key = item->text().replace(" ", "").toUpper();
if(key == "" || mifare->data_isKeyValid(key)) if(key == "" || mifare->data_isKeyValid(key))
{ {
mifare->data_setKey(item->row(), true, key); mifare->data_setKey(item->row(), Mifare::KEY_A, key);
} }
else else
{ {
QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)")); QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)"));
} }
mifare->data_syncWithKeyWidget(false, item->row(), true); mifare->data_syncWithKeyWidget(false, item->row(), Mifare::KEY_A);
} }
else if(item->column() == 2) else if(item->column() == 2)
{ {
QString key = item->text().replace(" ", ""); QString key = item->text().replace(" ", "").toUpper();
if(key == "" || mifare->data_isKeyValid(key)) if(key == "" || mifare->data_isKeyValid(key))
{ {
mifare->data_setKey(item->row(), false, key); mifare->data_setKey(item->row(), Mifare::KEY_B, key);
} }
else else
{ {
QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)")); QMessageBox::information(this, tr("Info"), tr("Key must consists of 12 Hex symbols(Whitespace is allowed)"));
} }
mifare->data_syncWithKeyWidget(false, item->row(), false); mifare->data_syncWithKeyWidget(false, item->row(), Mifare::KEY_B);
} }
} }
@@ -369,31 +668,31 @@ void MainWindow::on_MF_Attack_hardnestedButton_clicked()
mifare->hardnested(); mifare->hardnested();
} }
void MainWindow::on_MF_RW_readAllButton_clicked() void MainWindow::on_MF_RW_readSelectedButton_clicked()
{ {
setState(false); setState(false);
mifare->readAll(); mifare->readSelected(Mifare::TARGET_MIFARE);
setState(true); setState(true);
} }
void MainWindow::on_MF_RW_readBlockButton_clicked() void MainWindow::on_MF_RW_readBlockButton_clicked()
{ {
setState(false); setState(false);
mifare->read(); mifare->readOne(Mifare::TARGET_MIFARE);
setState(true); setState(true);
} }
void MainWindow::on_MF_RW_writeBlockButton_clicked() void MainWindow::on_MF_RW_writeBlockButton_clicked()
{ {
setState(false); setState(false);
mifare->write(); mifare->writeOne();
setState(true); setState(true);
} }
void MainWindow::on_MF_RW_writeAllButton_clicked() void MainWindow::on_MF_RW_writeSelectedButton_clicked()
{ {
setState(false); setState(false);
mifare->writeAll(); mifare->writeSelected(Mifare::TARGET_MIFARE);
setState(true); setState(true);
} }
@@ -407,31 +706,31 @@ void MainWindow::on_MF_RW_restoreButton_clicked()
mifare->restore(); mifare->restore();
} }
void MainWindow::on_MF_UID_readAllButton_clicked() void MainWindow::on_MF_UID_readSelectedButton_clicked()
{ {
setState(false); setState(false);
mifare->readAllC(); mifare->readSelected(Mifare::TARGET_UID);
setState(true); setState(true);
} }
void MainWindow::on_MF_UID_readBlockButton_clicked() void MainWindow::on_MF_UID_readBlockButton_clicked()
{ {
setState(false); setState(false);
mifare->readC(); mifare->readOne(Mifare::TARGET_UID);
setState(true); setState(true);
} }
void MainWindow::on_MF_UID_writeAllButton_clicked() void MainWindow::on_MF_UID_writeSelectedButton_clicked()
{ {
setState(false); setState(false);
mifare->writeAllC(); mifare->writeSelected(Mifare::TARGET_UID);
setState(true); setState(true);
} }
void MainWindow::on_MF_UID_writeBlockButton_clicked() void MainWindow::on_MF_UID_writeBlockButton_clicked()
{ {
setState(false); setState(false);
mifare->writeC(); mifare->writeOne(Mifare::TARGET_UID);
setState(true); setState(true);
} }
@@ -473,17 +772,17 @@ void MainWindow::on_MF_UID_lockButton_clicked()
mifare->lockC(); mifare->lockC();
} }
void MainWindow::on_MF_Sim_loadDataButton_clicked() void MainWindow::on_MF_Sim_readSelectedButton_clicked()
{ {
setState(false); setState(false);
mifare->writeAllE(); mifare->readSelected(Mifare::TARGET_EMULATOR);
setState(true); setState(true);
} }
void MainWindow::on_MF_Sim_writeAllButton_clicked() void MainWindow::on_MF_Sim_writeSelectedButton_clicked()
{ {
setState(false); setState(false);
mifare->readAllE(); mifare->writeSelected(Mifare::TARGET_EMULATOR);
setState(true); setState(true);
} }
@@ -548,6 +847,13 @@ void MainWindow::on_MF_Sniff_sniffButton_clicked()
setState(true); setState(true);
} }
void MainWindow::on_MF_14aSniff_snoopButton_clicked()
{
setState(false);
mifare->sniff14a();
setState(true);
}
void MainWindow::on_MF_Sniff_listButton_clicked() void MainWindow::on_MF_Sniff_listButton_clicked()
{ {
mifare->list(); mifare->list();
@@ -555,16 +861,23 @@ void MainWindow::on_MF_Sniff_listButton_clicked()
void MainWindow::MF_widgetReset() void MainWindow::MF_widgetReset()
{ {
int secs = mifare->cardType.sectors; int secs = mifare->cardType.sector_size;
int blks = mifare->cardType.blocks; int blks = mifare->cardType.block_size;
QBrush trailerItemForeColor = QBrush(QColor(0, 160, 255));
ui->MF_RW_blockBox->clear(); ui->MF_RW_blockBox->clear();
ui->MF_keyWidget->setRowCount(secs); ui->MF_keyWidget->setRowCount(secs);
ui->MF_dataWidget->setRowCount(blks); ui->MF_dataWidget->setRowCount(blks);
ui->MF_dataWidget->blockSignals(true);
ui->MF_keyWidget->blockSignals(true);
ui->MF_selectAllBox->blockSignals(true);
ui->MF_selectTrailerBox->blockSignals(true);
for(int i = 0; i < blks; i++) for(int i = 0; i < blks; i++)
{ {
setTableItem(ui->MF_dataWidget, i, 0, ""); setTableItem(ui->MF_dataWidget, i, 0, "");
setTableItem(ui->MF_dataWidget, i, 1, QString::number(i)); setTableItem(ui->MF_dataWidget, i, 1, QString::number(i));
ui->MF_dataWidget->item(i, 1)->setCheckState(Qt::Checked);
setTableItem(ui->MF_dataWidget, i, 2, ""); setTableItem(ui->MF_dataWidget, i, 2, "");
ui->MF_RW_blockBox->addItem(QString::number(i)); ui->MF_RW_blockBox->addItem(QString::number(i));
} }
@@ -575,7 +888,17 @@ void MainWindow::MF_widgetReset()
setTableItem(ui->MF_keyWidget, i, 1, ""); setTableItem(ui->MF_keyWidget, i, 1, "");
setTableItem(ui->MF_keyWidget, i, 2, ""); setTableItem(ui->MF_keyWidget, i, 2, "");
setTableItem(ui->MF_dataWidget, mifare->cardType.blks[i], 0, QString::number(i)); setTableItem(ui->MF_dataWidget, mifare->cardType.blks[i], 0, QString::number(i));
ui->MF_dataWidget->item(mifare->cardType.blks[i] + mifare->cardType.blk[i] - 1, 2)->setForeground(trailerItemForeColor);
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Checked);
} }
ui->MF_dataWidget->item(0, 2)->setForeground(QBrush(QColor(255, 160, 0)));
ui->MF_selectAllBox->setCheckState(Qt::Checked);
ui->MF_selectTrailerBox->setCheckState(Qt::Checked);
ui->MF_dataWidget->blockSignals(false);
ui->MF_keyWidget->blockSignals(false);
ui->MF_selectAllBox->blockSignals(false);
ui->MF_selectTrailerBox->blockSignals(false);
} }
// ************************************************ // ************************************************
@@ -585,63 +908,122 @@ void MainWindow::MF_widgetReset()
void MainWindow::uiInit() void MainWindow::uiInit()
{ {
connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG); connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG);
ui->Raw_CMDEdit->installEventFilter(keyEventFilter);
connect(keyEventFilter, &MyEventFilter::eventHappened, this, &MainWindow::on_Raw_CMDEdit_keyPressed);
ui->MF_keyWidget->installEventFilter(resizeEventFilter);
connect(resizeEventFilter, &MyEventFilter::eventHappened, this, &MainWindow::on_MF_keyWidget_resized);
connectStatusBar = new QLabel(this); connectStatusBar = new QLabel(this);
programStatusBar = new QLabel(this); programStatusBar = new QLabel(this);
PM3VersionBar = new QLabel(this); PM3VersionBar = new QLabel(this);
stopButton = new QPushButton(this);
setStatusBar(connectStatusBar, tr("Not Connected")); setStatusBar(connectStatusBar, tr("Not Connected"));
setStatusBar(programStatusBar, tr("Idle")); setStatusBar(programStatusBar, tr("Idle"));
setStatusBar(PM3VersionBar, ""); setStatusBar(PM3VersionBar, "");
stopButton->setText(tr("Stop"));
ui->statusbar->addPermanentWidget(PM3VersionBar, 1); ui->statusbar->addPermanentWidget(PM3VersionBar, 1);
ui->statusbar->addPermanentWidget(connectStatusBar, 1); ui->statusbar->addPermanentWidget(connectStatusBar, 1);
ui->statusbar->addPermanentWidget(programStatusBar, 1); ui->statusbar->addPermanentWidget(programStatusBar, 1);
ui->statusbar->addPermanentWidget(stopButton);
ui->MF_dataWidget->setColumnCount(3); ui->MF_dataWidget->setColumnCount(3);
ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec"))); ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Blk"))); ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Blk")));
ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Data"))); ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Data")));
ui->MF_dataWidget->verticalHeader()->setVisible(false); ui->MF_dataWidget->setColumnWidth(0, 55);
ui->MF_dataWidget->setColumnWidth(0, 35); ui->MF_dataWidget->setColumnWidth(1, 55);
ui->MF_dataWidget->setColumnWidth(1, 35);
ui->MF_dataWidget->setColumnWidth(2, 430);
ui->MF_keyWidget->setColumnCount(3); ui->MF_keyWidget->setColumnCount(3);
ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec"))); ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("KeyA"))); ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("KeyA")));
ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB"))); ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB")));
ui->MF_keyWidget->verticalHeader()->setVisible(false); ui->MF_keyWidget->setColumnWidth(0, 45);
ui->MF_keyWidget->setColumnWidth(0, 35);
ui->MF_keyWidget->setColumnWidth(1, 115);
ui->MF_keyWidget->setColumnWidth(2, 115);
MF_widgetReset(); MF_widgetReset();
typeBtnGroup = new QButtonGroup(this); MFCardTypeBtnGroup = new QButtonGroup(this);
typeBtnGroup->addButton(ui->MF_Type_miniButton, 0); MFCardTypeBtnGroup->addButton(ui->MF_Type_miniButton, 0);
typeBtnGroup->addButton(ui->MF_Type_1kButton, 1); MFCardTypeBtnGroup->addButton(ui->MF_Type_1kButton, 1);
typeBtnGroup->addButton(ui->MF_Type_2kButton, 2); MFCardTypeBtnGroup->addButton(ui->MF_Type_2kButton, 2);
typeBtnGroup->addButton(ui->MF_Type_4kButton, 4); MFCardTypeBtnGroup->addButton(ui->MF_Type_4kButton, 4);
connect(typeBtnGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MainWindow::MF_onTypeChanged); connect(MFCardTypeBtnGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), this, &MainWindow::MF_onMFCardTypeChanged);
ui->MF_keyWidget->installEventFilter(this); ui->MF_keyWidget->installEventFilter(this);
ui->MF_dataWidget->installEventFilter(this); ui->MF_dataWidget->installEventFilter(this);
settings->beginGroup("UI_grpbox_preference");
QStringList boxNames = settings->allKeys();
QGroupBox * boxptr;
foreach(QString name, boxNames)
{
boxptr = this->findChild<QGroupBox*>(name);
if(boxptr == nullptr)
continue;
if(settings->value(name, true).toBool())
{
boxptr->setMaximumHeight(16777215);
boxptr->setChecked(true);
}
else
{
boxptr->setMaximumHeight(20);
boxptr->setChecked(false);
}
}
settings->endGroup();
settings->beginGroup("Client_Path");
ui->PM3_pathEdit->setText(settings->value("path", "proxmark3").toString());
settings->endGroup();
settings->beginGroup("Client_Args");
ui->Set_Client_startArgsEdit->setText(settings->value("args", "<port> -f").toString());
settings->endGroup();
settings->beginGroup("Client_forceButtonsEnabled");
keepButtonsEnabled = settings->value("state", false).toBool();
ui->Set_Client_forceEnabledBox->setChecked(keepButtonsEnabled);
settings->endGroup();
settings->beginGroup("Client_Env");
ui->Set_Client_envScriptEdit->setText(settings->value("scriptPath").toString());
ui->Set_Client_workingDirEdit->setText(settings->value("workingDir", "../data").toString());
settings->endGroup();
ui->MF_RW_keyTypeBox->addItem("A", Mifare::KEY_A);
ui->MF_RW_keyTypeBox->addItem("B", Mifare::KEY_B);
on_Raw_CMDHistoryBox_stateChanged(Qt::Unchecked); on_Raw_CMDHistoryBox_stateChanged(Qt::Unchecked);
on_PM3_refreshPortButton_clicked();
} }
void MainWindow::signalInit() void MainWindow::signalInit()
{ {
connect(pm3, &PM3Process::newOutput, util, &Util::processOutput); connect(pm3, &PM3Process::newOutput, util, &Util::processOutput);
connect(pm3, &PM3Process::changeClientType, util, &Util::setClientType);
connect(util, &Util::refreshOutput, this, &MainWindow::refreshOutput); connect(util, &Util::refreshOutput, this, &MainWindow::refreshOutput);
connect(this, &MainWindow::connectPM3, pm3, &PM3Process::connectPM3); connect(this, &MainWindow::connectPM3, pm3, &PM3Process::connectPM3);
connect(this, &MainWindow::reconnectPM3, pm3, &PM3Process::reconnectPM3);
connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged); connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged);
connect(pm3, &PM3Process::PM3StatedChanged, util, &Util::setRunningState);
connect(this, &MainWindow::killPM3, pm3, &PM3Process::kill); connect(this, &MainWindow::killPM3, pm3, &PM3Process::kill);
connect(this, &MainWindow::setProcEnv, pm3, &PM3Process::setProcEnv);
connect(this, &MainWindow::setWorkingDir, pm3, &PM3Process::setWorkingDir);
connect(util, &Util::write, pm3, &PM3Process::write); connect(util, &Util::write, pm3, &PM3Process::write);
connect(ui->MF_typeGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
connect(ui->MF_fileGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
connect(ui->MF_RWGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
connect(ui->MF_normalGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
connect(ui->MF_UIDGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
connect(ui->MF_simGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
connect(ui->MF_sniffGroupBox, &QGroupBox::clicked, this, &MainWindow::on_GroupBox_clicked);
connect(stopButton, &QPushButton::clicked, this, &MainWindow::on_stopButton_clicked);
} }
void MainWindow::setStatusBar(QLabel* target, const QString & text) void MainWindow::setStatusBar(QLabel * target, const QString& text)
{ {
if(target == PM3VersionBar) if(target == PM3VersionBar)
target->setText(tr("HW Version:") + text); target->setText(tr("HW Version:") + text);
@@ -651,14 +1033,14 @@ void MainWindow::setStatusBar(QLabel* target, const QString & text)
target->setText(tr("State:") + text); target->setText(tr("State:") + text);
} }
void MainWindow::setTableItem(QTableWidget* widget, int row, int column, const QString& text) void MainWindow::setTableItem(QTableWidget * widget, int row, int column, const QString& text)
{ {
if(widget->item(row, column) == nullptr) if(widget->item(row, column) == nullptr)
widget->setItem(row, column, new QTableWidgetItem()); widget->setItem(row, column, new QTableWidgetItem());
widget->item(row, column)->setText(text); widget->item(row, column)->setText(text);
} }
bool MainWindow::eventFilter(QObject *watched, QEvent *event) // drag support bool MainWindow::eventFilter(QObject * watched, QEvent * event) // drag support
{ {
if(event->type() == QEvent::DragEnter) if(event->type() == QEvent::DragEnter)
{ {
@@ -709,6 +1091,11 @@ void MainWindow::setState(bool st)
{ {
setStatusBar(programStatusBar, tr("Idle")); setStatusBar(programStatusBar, tr("Idle"));
} }
setButtonsEnabled(st || keepButtonsEnabled);
}
void MainWindow::setButtonsEnabled(bool st)
{
ui->MF_attackGroupBox->setEnabled(st); ui->MF_attackGroupBox->setEnabled(st);
ui->MF_normalGroupBox->setEnabled(st); ui->MF_normalGroupBox->setEnabled(st);
ui->MF_UIDGroupBox->setEnabled(st); ui->MF_UIDGroupBox->setEnabled(st);
@@ -718,8 +1105,78 @@ void MainWindow::setState(bool st)
ui->Raw_sendCMDButton->setEnabled(st); ui->Raw_sendCMDButton->setEnabled(st);
} }
void MainWindow::on_GroupBox_clicked(bool checked)
{
QGroupBox* box = dynamic_cast<QGroupBox*>(sender());
settings->beginGroup("UI_grpbox_preference");
if(checked)
{
box->setMaximumHeight(16777215);
settings->setValue(box->objectName(), true);
}
else
{
box->setMaximumHeight(20);
settings->setValue(box->objectName(), false);
}
settings->endGroup();
}
void MainWindow::saveClientPath(const QString& path)
{
settings->beginGroup("Client_Path");
settings->setValue("path", path);
settings->endGroup();
}
// *********************************************** // ***********************************************
void MainWindow::on_MF_Attack_darksideButton_clicked()
{
setState(false);
mifare->darkside();
setState(true);
}
void MainWindow::on_Set_Client_startArgsEdit_editingFinished()
{
settings->beginGroup("Client_Args");
settings->setValue("args", ui->Set_Client_startArgsEdit->text());
settings->endGroup();
}
void MainWindow::on_Set_Client_forceEnabledBox_stateChanged(int arg1)
{
settings->beginGroup("Client_forceButtonsEnabled");
keepButtonsEnabled = (arg1 == Qt::Checked);
settings->setValue("state", keepButtonsEnabled);
settings->endGroup();
if(keepButtonsEnabled)
setButtonsEnabled(true);
}
void MainWindow::on_Set_GUI_setLanguageButton_clicked()
{
Util::chooseLanguage(settings, this);
}
void MainWindow::on_PM3_refreshPortButton_clicked()
{
on_portSearchTimer_timeout();
}
void MainWindow::on_Set_Client_envScriptEdit_editingFinished()
{
settings->beginGroup("Client_Env");
settings->setValue("scriptPath", ui->Set_Client_envScriptEdit->text());
settings->endGroup();
}
void MainWindow::on_Set_Client_saveWorkingDirButton_clicked()
{
settings->beginGroup("Client_Env");
settings->setValue("workingDir", ui->Set_Client_workingDirEdit->text());
settings->endGroup();
}
+82 -19
View File
@@ -16,10 +16,19 @@
#include <QMimeData> #include <QMimeData>
#include <QAction> #include <QAction>
#include <QDesktopServices> #include <QDesktopServices>
#include <QGroupBox>
#include <QSizePolicy>
#include <QSettings>
#include <QPushButton>
#include <QProcessEnvironment>
#include <QScrollBar>
#include <QTimer>
#include "common/myeventfilter.h"
#include "common/pm3process.h" #include "common/pm3process.h"
#include "module/mifare.h" #include "module/mifare.h"
#include "common/util.h" #include "common/util.h"
#include "ui/mf_trailerdecoderdialog.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui namespace Ui
@@ -39,11 +48,13 @@ public:
void initUI(); void initUI();
bool eventFilter(QObject *watched, QEvent *event); bool eventFilter(QObject *watched, QEvent *event);
public slots: public slots:
void refreshOutput(const QString &output); void refreshOutput(const QString& output);
void refreshCMD(const QString &cmd); void refreshCMD(const QString& cmd);
void setStatusBar(QLabel* target, const QString & text); void setStatusBar(QLabel* target, const QString& text);
void onPM3StateChanged(bool st, QString info); void onPM3StateChanged(bool st, const QString& info);
void MF_onTypeChanged(int id, bool st); void MF_onMFCardTypeChanged(int id, bool st);
void on_Raw_CMDEdit_keyPressed(QObject *obj_addr, QEvent &event);
void on_MF_keyWidget_resized(QObject *obj_addr, QEvent &event);
private slots: private slots:
void on_PM3_connectButton_clicked(); void on_PM3_connectButton_clicked();
@@ -55,7 +66,8 @@ private slots:
void on_Raw_clearOutputButton_clicked(); void on_Raw_clearOutputButton_clicked();
void sendMSG(); void sendMSG();
void on_PM3_refreshPortButton_clicked();
void on_portSearchTimer_timeout();
void on_Raw_CMDHistoryBox_stateChanged(int arg1); void on_Raw_CMDHistoryBox_stateChanged(int arg1);
@@ -73,7 +85,7 @@ private slots:
void on_MF_Sniff_listButton_clicked(); void on_MF_Sniff_listButton_clicked();
void on_MF_RW_readAllButton_clicked(); void on_MF_RW_readSelectedButton_clicked();
void on_MF_RW_readBlockButton_clicked(); void on_MF_RW_readBlockButton_clicked();
@@ -81,18 +93,17 @@ private slots:
void on_MF_Attack_infoButton_clicked(); void on_MF_Attack_infoButton_clicked();
void on_MF_RW_writeAllButton_clicked(); void on_MF_RW_writeSelectedButton_clicked();
void on_MF_RW_dumpButton_clicked(); void on_MF_RW_dumpButton_clicked();
void on_MF_RW_restoreButton_clicked(); void on_MF_RW_restoreButton_clicked();
void on_MF_UID_readAllButton_clicked(); void on_MF_UID_readSelectedButton_clicked();
void on_MF_UID_readBlockButton_clicked(); void on_MF_UID_readBlockButton_clicked();
void on_MF_UID_writeAllButton_clicked(); void on_MF_UID_writeSelectedButton_clicked();
void on_MF_UID_writeBlockButton_clicked(); void on_MF_UID_writeBlockButton_clicked();
@@ -100,9 +111,9 @@ private slots:
void on_MF_File_saveButton_clicked(); void on_MF_File_saveButton_clicked();
void on_MF_data2KeyBotton_clicked(); void on_MF_data2KeyButton_clicked();
void on_MF_key2DataBotton_clicked(); void on_MF_key2DataButton_clicked();
void on_MF_dataWidget_itemChanged(QTableWidgetItem *item); void on_MF_dataWidget_itemChanged(QTableWidgetItem *item);
@@ -120,9 +131,9 @@ private slots:
void on_MF_UID_lockButton_clicked(); void on_MF_UID_lockButton_clicked();
void on_MF_Sim_loadDataButton_clicked(); void on_MF_Sim_readSelectedButton_clicked();
void on_MF_Sim_writeAllButton_clicked(); void on_MF_Sim_writeSelectedButton_clicked();
void on_MF_Sim_clearButton_clicked(); void on_MF_Sim_clearButton_clicked();
@@ -132,31 +143,83 @@ private slots:
void on_MF_Sniff_saveButton_clicked(); void on_MF_Sniff_saveButton_clicked();
void on_GroupBox_clicked(bool checked);
void on_MF_selectAllBox_stateChanged(int arg1);
void on_MF_fillKeysButton_clicked();
void on_MF_14aSniff_snoopButton_clicked();
void on_MF_trailerDecoderButton_clicked();
void on_MF_selectTrailerBox_stateChanged(int arg1);
void on_stopButton_clicked();
void on_Raw_CMDEdit_textChanged(const QString &arg1);
void on_MF_Attack_darksideButton_clicked();
void on_Set_Client_startArgsEdit_editingFinished();
void on_Set_Client_forceEnabledBox_stateChanged(int arg1);
void on_Set_GUI_setLanguageButton_clicked();
void setButtonsEnabled(bool st);
void on_PM3_refreshPortButton_clicked();
void on_Set_Client_envScriptEdit_editingFinished();
void on_Set_Client_saveWorkingDirButton_clicked();
private: private:
Ui::MainWindow* ui; Ui::MainWindow* ui;
QButtonGroup* typeBtnGroup; QButtonGroup* MFCardTypeBtnGroup;
QLabel* connectStatusBar; QLabel* connectStatusBar;
QLabel* programStatusBar; QLabel* programStatusBar;
QLabel* PM3VersionBar; QLabel* PM3VersionBar;
QPushButton* stopButton;
QAction* myInfo; QAction* myInfo;
QAction* currVersion;
QAction* checkUpdate;
QSettings* settings;
MyEventFilter* keyEventFilter;
MyEventFilter* resizeEventFilter;
QString stashedCMDEditText;
int stashedIndex = -1;
void uiInit(); void uiInit();
PM3Process* pm3; PM3Process* pm3;
bool pm3state; bool pm3state;
bool keepButtonsEnabled;
QThread* pm3Thread; QThread* pm3Thread;
QTimer* portSearchTimer;
QStringList portList;
QStringList clientEnv;
QDir* clientWorkingDir;
Mifare* mifare; Mifare* mifare;
Util* util; Util* util;
MF_trailerDecoderDialog* decDialog;
void signalInit(); void signalInit();
void MF_widgetReset(); void MF_widgetReset();
void setTableItem(QTableWidget *widget, int row, int column, const QString &text); void setTableItem(QTableWidget *widget, int row, int column, const QString& text);
void setState(bool st); void setState(bool st);
void saveClientPath(const QString& path);
signals: signals:
void connectPM3(const QString path, const QString port); void connectPM3(const QString& path, const QString& port, const QStringList args);
void reconnectPM3();
void killPM3(); void killPM3();
void setSerialListener(const QString &name, bool state); void setSerialListener(const QString& name, bool state);
void setProcEnv(const QStringList *env);
void setWorkingDir(const QString& dir);
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H
+782 -96
View File
File diff suppressed because it is too large Load Diff
+22 -10
View File
@@ -21,14 +21,26 @@ MF_Attack_hardnestedDialog::~MF_Attack_hardnestedDialog()
void MF_Attack_hardnestedDialog::on_buttonBox_accepted() void MF_Attack_hardnestedDialog::on_buttonBox_accepted()
{ {
emit sendCMD("hf mf hardnested " if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
+ ui->knownKeySectorBox->currentText() emit sendCMD("hf mf hardnested "
+ " " + ui->knownKeySectorBox->currentText()
+ ui->knownKeyTypeBox->currentText() + " "
+ " " + ui->knownKeyTypeBox->currentText()
+ ui->knownKeyBox->text() + " "
+ " " + ui->knownKeyBox->text()
+ ui->targetKeySectorBox->currentText() + " "
+ " " + ui->targetKeySectorBox->currentText()
+ ui->targetKeyTypeBox->currentText()); + " "
+ ui->targetKeyTypeBox->currentText());
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
emit sendCMD("hf mf hardnested "
+ ui->knownKeySectorBox->currentText()
+ " "
+ ui->knownKeyTypeBox->currentText()
+ " "
+ ui->knownKeyBox->text()
+ " "
+ ui->targetKeySectorBox->currentText()
+ " "
+ ui->targetKeyTypeBox->currentText());
} }
+4 -2
View File
@@ -2,8 +2,10 @@
#define MF_ATTACK_HARDNESTEDDIALOG_H #define MF_ATTACK_HARDNESTEDDIALOG_H
#include <QDialog> #include <QDialog>
#include "common/util.h"
namespace Ui { namespace Ui
{
class MF_Attack_hardnestedDialog; class MF_Attack_hardnestedDialog;
} }
@@ -19,7 +21,7 @@ public:
private: private:
Ui::MF_Attack_hardnestedDialog *ui; Ui::MF_Attack_hardnestedDialog *ui;
signals: signals:
void sendCMD(QString cmd); void sendCMD(const QString& cmd);
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
}; };
+46 -9
View File
@@ -1,12 +1,34 @@
#include "mf_sim_simdialog.h" #include "mf_sim_simdialog.h"
#include "ui_mf_sim_simdialog.h" #include "ui_mf_sim_simdialog.h"
MF_Sim_simDialog::MF_Sim_simDialog(int cardType, QWidget *parent) : MF_Sim_simDialog::MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::MF_Sim_simDialog) ui(new Ui::MF_Sim_simDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
{
ui->atqaGroupBox->setVisible(false);
ui->atqaLine->setVisible(false);
ui->sakGroupBox->setVisible(false);
ui->sakLine->setVisible(false);
ui->vGroupBox->setVisible(false);
ui->vLine->setVisible(false);
}
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
{
ui->fGroupBox->setVisible(false);
ui->fLine->setVisible(false);
ui->rGroupBox->setVisible(false);
ui->rLine->setVisible(false);
ui->uBox->setText("-u");
ui->nBox->setText("-n");
ui->iBox->setText("-i");
ui->xBox->setText("--crack");
ui->eBox->setText("-e");
}
this->cardType = cardType; this->cardType = cardType;
this->cardTypeText = cardTypeText;
} }
MF_Sim_simDialog::~MF_Sim_simDialog() MF_Sim_simDialog::~MF_Sim_simDialog()
@@ -55,12 +77,27 @@ void MF_Sim_simDialog::on_fBox_clicked(bool checked)
void MF_Sim_simDialog::on_buttonBox_accepted() void MF_Sim_simDialog::on_buttonBox_accepted()
{ {
QString paras; QString paras;
paras += (ui->uBox->isChecked() ? "u " + ui->uEdit->text() + " " : ""); if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
paras += (ui->nBox->isChecked() ? "n " + ui->nEdit->text() + " " : ""); {
paras += (ui->iBox->isChecked() ? "i " : ""); paras += (ui->uBox->isChecked() ? "u " + ui->uEdit->text() + " " : "");
paras += (ui->xBox->isChecked() ? "x " : ""); paras += (ui->nBox->isChecked() ? "n " + ui->nEdit->text() + " " : "");
paras += (ui->eBox->isChecked() ? "e " : ""); paras += (ui->iBox->isChecked() ? "i " : "");
paras += (ui->fBox->isChecked() ? "f " + ui->fEdit->text() + " " : ""); paras += (ui->xBox->isChecked() ? "x " : "");
paras += (ui->rBox->isChecked() ? "r " : ""); paras += (ui->eBox->isChecked() ? "e " : "");
emit sendCMD(QString("hf mf sim ") + "*" + QString::number(cardType) + " " + paras.trimmed()); paras += (ui->fBox->isChecked() ? "f " + ui->fEdit->text() + " " : "");
paras += (ui->rBox->isChecked() ? "r " : "");
emit sendCMD(QString("hf mf sim ") + "*" + QString::number(cardType) + " " + paras.trimmed());
}
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN)
{
paras += (ui->uBox->isChecked() ? "-u " + ui->uEdit->text() + " " : "");
paras += (ui->atqaBox->isChecked() ? "--atqa " + ui->atqaEdit->text() + " " : "");
paras += (ui->sakBox->isChecked() ? "--sak " + ui->sakEdit->text() + " " : "");
paras += (ui->nBox->isChecked() ? "-n " + ui->nEdit->text() + " " : "");
paras += (ui->iBox->isChecked() ? "-i " : "");
paras += (ui->xBox->isChecked() ? "--crack " : "");
paras += (ui->eBox->isChecked() ? "-e " : "");
paras += (ui->vBox->isChecked() ? "-v " : "");
emit sendCMD(QString("hf mf sim --") + cardTypeText + " " + paras.trimmed());
}
} }
+4 -2
View File
@@ -3,6 +3,7 @@
#include <QDialog> #include <QDialog>
#include <QDebug> #include <QDebug>
#include "common/util.h"
namespace Ui namespace Ui
{ {
@@ -14,7 +15,7 @@ class MF_Sim_simDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
explicit MF_Sim_simDialog(int cardType, QWidget *parent = nullptr); explicit MF_Sim_simDialog(int cardType, QString cardTypeText, QWidget *parent = nullptr);
~MF_Sim_simDialog(); ~MF_Sim_simDialog();
private slots: private slots:
@@ -25,8 +26,9 @@ private slots:
private: private:
Ui::MF_Sim_simDialog *ui; Ui::MF_Sim_simDialog *ui;
int cardType; int cardType;
QString cardTypeText;
signals: signals:
void sendCMD(QString cmd); void sendCMD(const QString& cmd);
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
}; };
+535 -246
View File
@@ -7,309 +7,598 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>461</width> <width>461</width>
<height>456</height> <height>524</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Simulate</string> <string>Simulate</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <widget class="QGroupBox" name="uGroupBox">
<item> <layout class="QHBoxLayout" name="uLayout">
<widget class="QCheckBox" name="uBox"> <property name="spacing">
<property name="text"> <number>5</number>
<string>u</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QLineEdit" name="uEdit"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <property name="rightMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="bottomMargin">
</property> <number>0</number>
<property name="maximumSize"> </property>
<size> <item>
<width>100</width> <widget class="QCheckBox" name="uBox">
<height>16777215</height> <property name="text">
</size> <string>u</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label"> <widget class="QLineEdit" name="uEdit">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="maximumSize">
<string>UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used</string> <size>
</property> <width>100</width>
<property name="wordWrap"> <height>16777215</height>
<bool>true</bool> </size>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>UID 4 or 7 bytes. If not specified, the UID 4B from emulator memory will be used</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<widget class="Line" name="line_6"> <widget class="Line" name="uLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <widget class="QGroupBox" name="atqaGroupBox">
<item> <layout class="QHBoxLayout" name="atqaLayout">
<widget class="QCheckBox" name="nBox"> <property name="spacing">
<property name="text"> <number>5</number>
<string>n</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QLineEdit" name="nEdit"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <property name="rightMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="bottomMargin">
</property> <number>0</number>
<property name="maximumSize"> </property>
<size> <item>
<width>100</width> <widget class="QCheckBox" name="atqaBox">
<height>16777215</height> <property name="text">
</size> <string>--atqa</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_2"> <widget class="QLineEdit" name="atqaEdit">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="maximumSize">
<string>Automatically exit simulation after &lt;numreads&gt; blocks have been read by reader. 0 = infinite</string> <size>
</property> <width>100</width>
<property name="wordWrap"> <height>16777215</height>
<bool>true</bool> </size>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item>
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Provide explicit ATQA (2 bytes)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<widget class="Line" name="line_5"> <widget class="Line" name="atqaLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_4"> <widget class="QGroupBox" name="sakGroupBox">
<item> <layout class="QHBoxLayout" name="sakLayout">
<widget class="QCheckBox" name="iBox"> <property name="spacing">
<property name="text"> <number>5</number>
<string>i</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QLabel" name="label_3"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <property name="rightMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="bottomMargin">
</property> <number>0</number>
<property name="text"> </property>
<string>Interactive, means that console will not be returned until simulation finishes or is aborted</string> <item>
</property> <widget class="QCheckBox" name="sakBox">
<property name="wordWrap"> <property name="text">
<bool>true</bool> <string>--sak</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item>
<widget class="QLineEdit" name="sakEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Provide explicit SAK (1 byte)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<widget class="Line" name="line_4"> <widget class="Line" name="sakLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <widget class="QGroupBox" name="nGroupBox">
<item> <layout class="QHBoxLayout" name="nLayout">
<widget class="QCheckBox" name="xBox"> <property name="spacing">
<property name="text"> <number>5</number>
<string>x</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QLabel" name="label_4"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <property name="rightMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="bottomMargin">
</property> <number>0</number>
<property name="text"> </property>
<string>Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)</string> <item>
</property> <widget class="QCheckBox" name="nBox">
<property name="wordWrap"> <property name="text">
<bool>true</bool> <string>n</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item>
<widget class="QLineEdit" name="nEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatically exit simulation after &lt;numreads&gt; blocks have been read by reader. 0 = infinite</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<widget class="Line" name="line_3"> <widget class="Line" name="nLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_6"> <widget class="QGroupBox" name="iGroupBox">
<item> <layout class="QHBoxLayout" name="iLayout">
<widget class="QCheckBox" name="eBox"> <property name="spacing">
<property name="text"> <number>5</number>
<string>e</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QLabel" name="label_5"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <property name="rightMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="bottomMargin">
</property> <number>0</number>
<property name="text"> </property>
<string>set keys found from 'reader attack' to emulator memory (implies x and i)</string> <item>
</property> <widget class="QCheckBox" name="iBox">
<property name="wordWrap"> <property name="text">
<bool>true</bool> <string>i</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Interactive, means that console will not be returned until simulation finishes or is aborted</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<widget class="Line" name="line_2"> <widget class="Line" name="iLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <widget class="QGroupBox" name="xGroupBox">
<item> <layout class="QHBoxLayout" name="xLayout">
<widget class="QCheckBox" name="fBox"> <property name="spacing">
<property name="text"> <number>5</number>
<string>f</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QLineEdit" name="fEdit"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <property name="rightMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="bottomMargin">
</property> <number>0</number>
<property name="maximumSize"> </property>
<size> <item>
<width>100</width> <widget class="QCheckBox" name="xBox">
<height>16777215</height> <property name="text">
</size> <string>x</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_4">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>get UIDs to use for 'reader attack' from file 'f &lt;filename.txt&gt;' (implies x and i)</string> <string>Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget>
</item> </item>
<item> <item>
<widget class="Line" name="line"> <widget class="Line" name="xLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_7"> <widget class="QGroupBox" name="eGroupBox">
<item> <layout class="QHBoxLayout" name="eLayout">
<widget class="QCheckBox" name="rBox"> <property name="spacing">
<property name="text"> <number>5</number>
<string>r</string> </property>
</property> <property name="leftMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="topMargin">
<widget class="QLabel" name="label_7"> <number>0</number>
<property name="sizePolicy"> </property>
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <property name="rightMargin">
<horstretch>0</horstretch> <number>0</number>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="bottomMargin">
</property> <number>0</number>
<property name="text"> </property>
<string>Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works</string> <item>
</property> <widget class="QCheckBox" name="eBox">
<property name="wordWrap"> <property name="text">
<bool>true</bool> <string>e</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item>
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>set keys found from 'reader attack' to emulator memory (implies x(--crack) and i)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item> </item>
<item> <item>
<widget class="Line" name="line_7"> <widget class="Line" name="eLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="fGroupBox">
<layout class="QHBoxLayout" name="fLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="fBox">
<property name="text">
<string>f</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="fEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>get UIDs to use for 'reader attack' from file 'f &lt;filename.txt&gt;' (implies x and i)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="fLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="rGroupBox">
<layout class="QHBoxLayout" name="rLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="rBox">
<property name="text">
<string>r</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Generate random nonces instead of sequential nonces. Standard reader attack won't work with this option, only moebius attack works</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="rLine">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="vGroupBox">
<layout class="QHBoxLayout" name="vLayout">
<property name="spacing">
<number>5</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="vBox">
<property name="text">
<string>-v</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>verbose output</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="vLine">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
+154
View File
@@ -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);
}
+39
View File
@@ -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
+402
View File
@@ -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 &quot;FF0780&quot; or &quot;FF 07 80&quot;)</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>
+14 -6
View File
@@ -18,10 +18,18 @@ MF_UID_parameterDialog::~MF_UID_parameterDialog()
void MF_UID_parameterDialog::on_buttonBox_accepted() void MF_UID_parameterDialog::on_buttonBox_accepted()
{ {
emit sendCMD("hf mf csetuid " if(Util::getClientType() == Util::CLIENTTYPE_OFFICIAL)
+ ui->UIDLineEdit->text() emit sendCMD("hf mf csetuid "
+ " " + ui->UIDLineEdit->text()
+ ui->ATQALineEdit->text() + " "
+ " " + ui->ATQALineEdit->text()
+ ui->SAKLineEdit->text()); + " "
+ ui->SAKLineEdit->text());
else if(Util::getClientType() == Util::CLIENTTYPE_ICEMAN) // same format in v4.9237
emit sendCMD("hf mf csetuid "
+ ui->UIDLineEdit->text()
+ " "
+ ui->ATQALineEdit->text()
+ " "
+ ui->SAKLineEdit->text());
} }
+4 -2
View File
@@ -2,8 +2,10 @@
#define MF_UID_PARAMETERDIALOG_H #define MF_UID_PARAMETERDIALOG_H
#include <QDialog> #include <QDialog>
#include "common/util.h"
namespace Ui { namespace Ui
{
class MF_UID_parameterDialog; class MF_UID_parameterDialog;
} }
@@ -18,7 +20,7 @@ public:
private: private:
Ui::MF_UID_parameterDialog *ui; Ui::MF_UID_parameterDialog *ui;
signals: signals:
void sendCMD(QString cmd); void sendCMD(const QString& cmd);
private slots: private slots:
void on_buttonBox_accepted(); void on_buttonBox_accepted();
}; };