diff --git a/lang/en_US.ts b/lang/en_US.ts
index acc7497..b881d0e 100644
--- a/lang/en_US.ts
+++ b/lang/en_US.ts
@@ -290,552 +290,554 @@ It could make the whole sector blocked irreversibly!
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
-
+
320
-
+
1024
-
+
2048
-
+
4096
-
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
-
+
+
-
-
-
-
-
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
-
+
+
+
-
-
+
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
+
+
+
-
+
-
+
+
+
+
+
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -843,18 +845,15 @@ It could make the whole sector blocked irreversibly!
Mifare
-
-
+
-
-
-
-
-
+
+
+
@@ -864,14 +863,13 @@ It could make the whole sector blocked irreversibly!
-
-
-
+
+
-
+
diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts
index 2035f0b..316cf77 100644
--- a/lang/zh_CN.ts
+++ b/lang/zh_CN.ts
@@ -294,552 +294,554 @@ It could make the whole sector blocked irreversibly!
路径:
-
+
刷新端口
-
+
连接
-
+
断开
-
+
Mifare(IC)卡
-
+
+
+ 选中密码块
+
+
+
卡类型
-
+
320
-
+
1024
-
+
2048
-
+
4096
-
+
文件
-
-
+
+
加载
-
-
+
+
保存
-
-
+
+
-
+
-
+
破解
-
+
读卡片信息
-
+
验证默认密码
-
+
Nested攻击
-
+
Hardested攻击
-
+
读/写
-
+
-
+
-
+
Key类型:
-
+
嗅探(Snoop)
-
+
列出嗅探数据
-
+
-
+
普通卡(需要密码)
-
-
- 读所有块
-
-
-
+
Dump命令
-
+
Restore命令
-
+
UID卡(不需要密码)
-
+
锁定UFUID卡
-
-
+
+
关于UID卡
-
+
设置卡参数
-
+
擦除
-
-
+
+
模拟
-
-
- 从上方数据导入
-
-
-
-
+
+
清空
-
+
全选
-
+
密码区->密码
-
+
密码区<-密码
-
+
填充密码
-
+
Trailer解码
-
+
设置字体
-
-
+
+
读取单个区
-
-
+
+
写入单个区
-
-
+
+
+
读取选中块
-
-
+
+
+
写入选中块
-
-
+
+
嗅探
-
+
原始命令
-
-
+
+
命令历史:
-
+
清空历史
-
+
发送
-
+
清空输出
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
信息
-
+
请先选择端口
-
+
已连接
-
-
-
+
+
+
未连接
-
+
二进制Data文件(*.bin *.dump);;文本Data文件(*.txt *.eml);;所有文件(*.*)
-
-
-
+
+
+
无法打开
-
+
确定?
-
+
+
+ 检查更新
+
+
+
部分数据和密码将被清除
-
+
请选择Data窗口和Key窗口的字体
-
+
Data必须由32个十六进制字符组成(中间可含有空格)
-
-
+
+
Key必须由12个十六进制字符组成(中间可含有空格)
-
+
请选择data文件:
-
+
请选择key文件:
-
+
二进制Key文件(*.bin *.dump)二进制Data文件(*.bin *.dump);;所有文件(*.*)
-
+
请选择文件保存的位置:
-
+
二进制Data文件(*.bin *.dump);;文本Data文件(*.txt *.eml)
-
-
-
+
+
+
无法保存至
-
+
请选择key文件保存的位置:
-
+
二进制Key文件(*.bin *.dump)
-
+
普通Mifare卡的Block0无法写入,UID也不能更改
-
+
UID卡(在国外叫Chinese Magic Card)的Block0可写,UID可变
-
+
国外把UID卡分为Chinese Magic Card Gen1和Gen2
-
+
-
+
指通常所说的UID卡,可以通过后门指令直接读写块而无需密码,在PM3和此GUI中有特殊命令处理这类卡片
-
+
-
+
这个叫法在国内比较罕见,在国外指CUID/FUID/UFUID这类对后门指令不响应的卡(防火墙卡)
-
+
以下是Gen2卡的详细介绍
-
+
CUID卡:
-
+
可通过普通的写块命令来写Block0,可重复擦写
-
+
(hf mf wrbl 0 A FFFFFFFFFFFF <待写入数据>)
-
+
FUID卡:
-
+
Block0只能写入一次
-
+
(更高级的穿防火墙卡,可以过一些能识别出CUID卡的读卡器)
-
+
UFUID卡:
-
+
锁卡前和普通UID/CUID卡一样可以反复读写Block0,用特殊命令锁卡后就和FUID卡一样了
-
+
所有UID卡都似乎更容易被Nested攻击破解
-
+
请选择trace文件:
-
+
Trace文件(*.trc);;所有文件(*.*)
-
+
请选择trace文件保存的位置:
-
+
Trace文件(*.trc)
-
-
+
+
空闲
-
-
+
+
-
+
-
+
-
+
-
+
固件版本:
-
+
连接状态:
-
+
运行状态:
-
+
运行中
@@ -847,18 +849,15 @@ It could make the whole sector blocked irreversibly!
Mifare
-
-
+
成功!
-
-
-
-
-
+
+
+
信息
@@ -868,14 +867,13 @@ It could make the whole sector blocked irreversibly!
请至少提供一个已知密码
-
-
-
+
+
失败!
-
+
读卡失败。
diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp
index 6b33e30..fc350cf 100644
--- a/ui/mainwindow.cpp
+++ b/ui/mainwindow.cpp
@@ -7,11 +7,17 @@ MainWindow::MainWindow(QWidget *parent):
{
ui->setupUi(this);
myInfo = new QAction("wh201906", this);
+ checkUpdate = new QAction(tr("Check Update"), this);
connect(myInfo, &QAction::triggered, [ = ]()
{
QDesktopServices::openUrl(QUrl("https://github.com/wh201906"));
});
+ connect(checkUpdate, &QAction::triggered, [ = ]()
+ {
+ QDesktopServices::openUrl(QUrl("https://github.com/wh201906/Proxmark3GUI/releases"));
+ });
this->addAction(myInfo);
+ this->addAction(checkUpdate);
settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
@@ -206,6 +212,7 @@ 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);
@@ -219,10 +226,54 @@ void MainWindow::on_MF_selectAllBox_stateChanged(int arg1)
{
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();
@@ -260,6 +311,7 @@ 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;
@@ -278,34 +330,40 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
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;
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)
{
@@ -331,6 +389,18 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
{
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)
{
@@ -347,6 +417,7 @@ void MainWindow::on_MF_dataWidget_itemChanged(QTableWidgetItem *item)
}
ui->MF_dataWidget->blockSignals(false);
ui->MF_selectAllBox->blockSignals(false);
+ ui->MF_selectTrailerBox->blockSignals(false);
}
void MainWindow::on_MF_keyWidget_itemChanged(QTableWidgetItem *item)
@@ -691,6 +762,7 @@ void MainWindow::MF_widgetReset()
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++)
{
@@ -710,10 +782,12 @@ void MainWindow::MF_widgetReset()
ui->MF_dataWidget->item(mifare->cardType.blks[i], 0)->setCheckState(Qt::Checked);
}
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);
}
// ************************************************
diff --git a/ui/mainwindow.h b/ui/mainwindow.h
index 9f19b29..873f6d4 100644
--- a/ui/mainwindow.h
+++ b/ui/mainwindow.h
@@ -146,6 +146,8 @@ private slots:
void on_MF_trailerDecoderButton_clicked();
+ void on_MF_selectTrailerBox_stateChanged(int arg1);
+
private:
Ui::MainWindow* ui;
QButtonGroup* typeBtnGroup;
@@ -153,6 +155,7 @@ private:
QLabel* programStatusBar;
QLabel* PM3VersionBar;
QAction* myInfo;
+ QAction* checkUpdate;
QSettings* settings;
void uiInit();
diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui
index 42e918e..edd93f4 100644
--- a/ui/mainwindow.ui
+++ b/ui/mainwindow.ui
@@ -201,24 +201,31 @@
Select All
-
- false
-
-
-
-
- 40
- 0
-
-
Select Trailer
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Fixed
+
+
+
+ 20
+ 20
+
+
+
+
-
@@ -530,12 +537,6 @@
0
-
-
- 40
- 0
-
-
Check Default
@@ -660,7 +661,7 @@
- 35
+ 45
0