diff --git a/README.md b/README.md index 07e6c72..02c691d 100644 --- a/README.md +++ b/README.md @@ -72,6 +72,7 @@ Great thanks to him. + 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 diff --git a/README/doc/README_zh_CN.md b/README/doc/README_zh_CN.md index 7d4605d..9ae017d 100644 --- a/README/doc/README_zh_CN.md +++ b/README/doc/README_zh_CN.md @@ -71,6 +71,7 @@ release页面中有含客户端的GUI。这个GUI也可以搭配你自己的客 + 可通过外部脚本配置环境变量 (在客户端需要配置环境变量时很有用) + 全功能兼容冰人版(在v4.9237上测试通过) ++ 支持指定客户端工作路径 + 修复部分bug ### V0.1.3 diff --git a/common/pm3process.cpp b/common/pm3process.cpp index a80397c..35d59e1 100644 --- a/common/pm3process.cpp +++ b/common/pm3process.cpp @@ -55,7 +55,11 @@ void PM3Process::connectPM3(const QString& path, const QString& port, const QStr result = result.left(result.indexOf("\r\n")); result = result.mid(3, result.lastIndexOf(" ") - 3); emit PM3StatedChanged(true, result); - setSerialListener(port, true); + + // if the arguments don't contain , then disable the port listener + // useful when using offline sniff + if(args.indexOf(port) != -1) + setSerialListener(port, true); } else kill(); @@ -132,5 +136,11 @@ void PM3Process::setProcEnv(const QStringList* env) { // qDebug() << "passed Env List" << *env; this->setEnvironment(*env); -// qDebug() << "final Env List" << processEnvironment().toStringList(); + // 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); } diff --git a/common/pm3process.h b/common/pm3process.h index b2a6631..7b0e253 100644 --- a/common/pm3process.h +++ b/common/pm3process.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "util.h" @@ -27,6 +28,7 @@ public slots: qint64 write(QString data); void reconnectPM3(); void setProcEnv(const QStringList* env); + void setWorkingDir(const QString& dir); private slots: void onTimeout(); void onReadyRead(); diff --git a/lang/en_US.ts b/lang/en_US.ts index f73b0da..60f26b2 100644 --- a/lang/en_US.ts +++ b/lang/en_US.ts @@ -377,12 +377,13 @@ It could make the whole sector blocked irreversibly! + Save - + Data @@ -478,7 +479,7 @@ It could make the whole sector blocked irreversibly! - + About UID Card @@ -658,7 +659,7 @@ It could make the whole sector blocked irreversibly! - + History: @@ -701,16 +702,32 @@ then put the path of the script there + Client working directory: + + + + + ../data + + + + + Note: +On Windows, the client working directory should not be identical to the path of GUI, otherwise the client will use the wrong .dll file. + + + + Start arguments - + <port> -f - + Note: -f is necessary because the GUI need to handle the output in time In some cases the arguments should be set to "-p /dev/<port> -f" @@ -718,75 +735,75 @@ or "-p <port> -f" - + Keep buttons enabled even the client is running or disconnected - + GUI - + Language: - + Choose Language - + (Restart this app to use new language) - - - - - - - - - - - + + + + + + + + + + + Info - + Plz choose a port first - + Connected - - + + Not Connected - + Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml);;All Files(*.*) - - - + + + Failed to open - + Continue? @@ -796,222 +813,222 @@ or "-p <port> -f" - + Some of the data and key will be cleared. - + Plz select the font of data widget and key widget - + Data must consists of 32 Hex symbols(Whitespace is allowed) - - + + Key must consists of 12 Hex symbols(Whitespace is allowed) - + Plz select the data file: - + Plz select the key file: - + Binary Key Files(*.bin *.dump);;Binary Data Files(*.bin *.dump);;All Files(*.*) - + Plz select the location to save data file: - + Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml) - - - + + + Failed to save to - + Plz select the location to save key file: - + Binary Key Files(*.bin *.dump) - + Normally, the Block 0 of a typical Mifare card, which contains the UID, is locked during the manufacture. Users cannot write anything to Block 0 or set a new UID to a normal Mifare card. - + Chinese Magic Cards(aka UID Cards) are some special cards whose Block 0 are writeable. And you can change UID by writing to it. - + There are two versions of Chinese Magic Cards, the Gen1 and the Gen2. - + Gen1: - + also called UID card in China. It responses to some backdoor commands so you can access any blocks without password. The Proxmark3 has a bunch of related commands(csetblk, cgetblk, ...) to deal with this type of card, and my GUI also support these commands. - + Gen2: - + doesn't response to the backdoor commands, which means that a reader cannot detect whether it is a Chinese Magic Card or not by sending backdoor commands. - + There are some types of Chinese Magic Card Gen2. - + CUID Card: - + the Block 0 is writeable, you can write to this block repeatedly by normal wrbl command. - + (hf mf wrbl 0 A FFFFFFFFFFFF <the data you want to write>) - + FUID Card: - + you can only write to Block 0 once. After that, it seems like a typical Mifare card(Block 0 cannot be written to). - + (some readers might try changing the Block 0, which could detect the CUID Card. In that case, you should use FUID card.) - + UFUID Card: - + It behaves like a CUID card(or UID card? I'm not sure) before you send some special command to lock it. Once it is locked, you cannot change its Block 0(just like a typical Mifare card). - + Seemingly, these Chinese Magic Cards are more easily to be compromised by Nested Attack(it takes little time to get an unknown key). - + Plz select the trace file: - + Trace Files(*.trc);;All Files(*.*) - + Plz select the location to save trace file: - + Trace Files(*.trc) - - + + Idle - + Stop - - + + Sec - + Blk - + KeyA - + KeyB - + HW Version: - + PM3: - + State: - + Running @@ -1019,56 +1036,56 @@ or "-p <port> -f" Mifare - + Success! - - - - - - - + + + + + + + Info - + Plz provide at least one known key - - + + Failed! - + The Access Bits is invalid! It could make the whole sector blocked irreversibly! Continue to write? - + Successful! - + Failed to write to these blocks: - + Select them? - + Failed to read card. diff --git a/lang/zh_CN.qm b/lang/zh_CN.qm index 3edc62a..3ab4033 100644 Binary files a/lang/zh_CN.qm and b/lang/zh_CN.qm differ diff --git a/lang/zh_CN.ts b/lang/zh_CN.ts index 3efde9e..415074d 100644 --- a/lang/zh_CN.ts +++ b/lang/zh_CN.ts @@ -381,12 +381,13 @@ It could make the whole sector blocked irreversibly! + Save 保存 - + Data 数据 @@ -482,7 +483,7 @@ It could make the whole sector blocked irreversibly! - + About UID Card 关于UID卡 @@ -662,7 +663,7 @@ It could make the whole sector blocked irreversibly! - + History: 命令历史: @@ -706,16 +707,33 @@ then put the path of the script there + Client working directory: + 客户端工作路径: + + + + ../data + + + + + Note: +On Windows, the client working directory should not be identical to the path of GUI, otherwise the client will use the wrong .dll file. + 注意: +在Windows系统中,客户端工作路径与GUI程序所在路径不能相同,否则客户端会使用错误的.dll文件。 + + + Start arguments 启动参数 - + <port> -f - + Note: -f is necessary because the GUI need to handle the output in time In some cases the arguments should be set to "-p /dev/<port> -f" @@ -726,75 +744,75 @@ or "-p <port> -f" 或"-p <port> -f" - + Language: 语言: - + Choose Language 选择语言 - + (Restart this app to use new language) (重启此程序以使用新语言) - + Keep buttons enabled even the client is running or disconnected 保持所有按钮可点击,即使未连接客户端或有任务正在运行 - + GUI 图形化界面 - - - - - - - - - - - + + + + + + + + + + + Info 信息 - + Plz choose a port first 请先选择端口 - + Connected 已连接 - - + + Not Connected 未连接 - + Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml);;All Files(*.*) 二进制数据文件(*.bin *.dump);;文本数据文件(*.txt *.eml);;所有文件(*.*) - - - + + + Failed to open 无法打开 - + Continue? 确定? @@ -804,222 +822,222 @@ or "-p <port> -f" 检查更新 - + Some of the data and key will be cleared. 部分数据和密码将被清除 - + Plz select the font of data widget and key widget 请选择数据窗口和密钥窗口的字体 - + Data must consists of 32 Hex symbols(Whitespace is allowed) 数据必须由32个十六进制字符组成(中间可含有空格) - - + + Key must consists of 12 Hex symbols(Whitespace is allowed) 密钥必须由12个十六进制字符组成(中间可含有空格) - + Plz select the data file: 请选择数据文件: - + Plz select the key file: 请选择密钥文件: - + Binary Key Files(*.bin *.dump);;Binary Data Files(*.bin *.dump);;All Files(*.*) 二进制密钥文件(*.bin *.dump)二进制密钥文件(*.bin *.dump);所有文件(*.*) - + Plz select the location to save data file: 请选择数据文件保存的位置: - + Binary Data Files(*.bin *.dump);;Text Data Files(*.txt *.eml) 二进制数据文件(*.bin *.dump);文本数据文件(*.txt *.eml) - - - + + + Failed to save to 无法保存至 - + Plz select the location to save key file: 请选择密钥文件保存的位置: - + Binary Key Files(*.bin *.dump) 二进制密码文件(*.bin *.dump) - + Normally, the Block 0 of a typical Mifare card, which contains the UID, is locked during the manufacture. Users cannot write anything to Block 0 or set a new UID to a normal Mifare card. 普通Mifare卡的块0无法写入,卡号也不能更改 - + Chinese Magic Cards(aka UID Cards) are some special cards whose Block 0 are writeable. And you can change UID by writing to it. UID卡(在国外叫Chinese Magic Card)的块0可写,卡号可变。 - + There are two versions of Chinese Magic Cards, the Gen1 and the Gen2. 国外把UID卡分为Chinese Magic Card Gen1和Gen2 - + Gen1: - + also called UID card in China. It responses to some backdoor commands so you can access any blocks without password. The Proxmark3 has a bunch of related commands(csetblk, cgetblk, ...) to deal with this type of card, and my GUI also support these commands. 指通常所说的UID卡,可以通过后门指令直接读写块而无需密码,在PM3和此GUI中有特殊命令处理这类卡片 - + Gen2: - + doesn't response to the backdoor commands, which means that a reader cannot detect whether it is a Chinese Magic Card or not by sending backdoor commands. 这个叫法在国内比较罕见,在国外指CUID/FUID/UFUID这类对后门指令不响应的卡(防火墙卡) - + There are some types of Chinese Magic Card Gen2. 以下是Gen2卡的详细介绍 - + CUID Card: CUID卡: - + the Block 0 is writeable, you can write to this block repeatedly by normal wrbl command. 可通过普通的写块命令来写块0,可重复擦写 - + (hf mf wrbl 0 A FFFFFFFFFFFF <the data you want to write>) (hf mf wrbl 0 A FFFFFFFFFFFF <待写入数据>) - + FUID Card: FUID卡: - + you can only write to Block 0 once. After that, it seems like a typical Mifare card(Block 0 cannot be written to). 块0只能写入一次 - + (some readers might try changing the Block 0, which could detect the CUID Card. In that case, you should use FUID card.) (更高级的穿防火墙卡,可以过一些能识别出CUID卡的读卡器) - + UFUID Card: UFUID卡: - + It behaves like a CUID card(or UID card? I'm not sure) before you send some special command to lock it. Once it is locked, you cannot change its Block 0(just like a typical Mifare card). 锁卡前和普通UID/CUID卡一样可以反复读写块0,用特殊命令锁卡后就和FUID卡一样了 - + Seemingly, these Chinese Magic Cards are more easily to be compromised by Nested Attack(it takes little time to get an unknown key). 所有UID卡都似乎更容易被Nested攻击破解 - + Plz select the trace file: 请选择trace文件: - + Trace Files(*.trc);;All Files(*.*) Trace文件(*.trc);;所有文件(*.*) - + Plz select the location to save trace file: 请选择trace文件保存的位置: - + Trace Files(*.trc) Trace文件(*.trc) - - + + Idle 空闲 - + Stop 停止 - - + + Sec 扇区 - + Blk - + KeyA 密钥A - + KeyB 密钥B - + HW Version: 固件版本: - + PM3: 连接状态: - + State: 运行状态: - + Running 正在运行 @@ -1027,34 +1045,34 @@ or "-p <port> -f" Mifare - + Success! 成功! - - - - - - - + + + + + + + Info 信息 - + Plz provide at least one known key 请至少提供一个已知密码 - - + + Failed! 失败! - + The Access Bits is invalid! It could make the whole sector blocked irreversibly! Continue to write? @@ -1063,22 +1081,22 @@ Continue to write? 确定要写入吗? - + Successful! 成功! - + Failed to write to these blocks: 写入以下块失败: - + Select them? 选中这些块? - + Failed to read card. 读卡失败。 diff --git a/module/mifare.cpp b/module/mifare.cpp index 064a9ae..204d03a 100644 --- a/module/mifare.cpp +++ b/module/mifare.cpp @@ -102,16 +102,14 @@ QString Mifare::info(bool isRequiringOutput) end = result.indexOf("\n", end); return result.mid(begin, end - begin + 1); } - else - return ""; } else { util->execCMD("hf 14a info"); ui->funcTab->setCurrentIndex(Util::rawTabIndex); - return ""; } } + return ""; } void Mifare::chk() @@ -629,6 +627,7 @@ bool Mifare::_writeblk(int blockId, KeyType keyType, const QString& key, const Q return true; } } + return false; } void Mifare::writeOne(TargetType targetType) diff --git a/ui/mainwindow.cpp b/ui/mainwindow.cpp index 673acdc..bc14ce0 100644 --- a/ui/mainwindow.cpp +++ b/ui/mainwindow.cpp @@ -28,6 +28,7 @@ MainWindow::MainWindow(QWidget *parent): pm3 = new PM3Process(pm3Thread); pm3Thread->start(); pm3state = false; + clientWorkingDir = new QDir; util = new Util(this); mifare = new Mifare(ui, util, this); @@ -94,6 +95,7 @@ void MainWindow::on_PM3_connectButton_clicked() { QStringList args = ui->Set_Client_startArgsEdit->text().replace("", port).split(' '); saveClientPath(ui->PM3_pathEdit->text()); + QProcess envSetProcess; QFileInfo envScriptPath(ui->Set_Client_envScriptEdit->text()); if(envScriptPath.exists()) @@ -113,6 +115,15 @@ void MainWindow::on_PM3_connectButton_clicked() 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); } } @@ -976,6 +987,7 @@ void MainWindow::uiInit() 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); @@ -996,6 +1008,7 @@ void MainWindow::signalInit() connect(pm3, &PM3Process::PM3StatedChanged, util, &Util::setRunningState); connect(this, &MainWindow::killPM3, pm3, &PM3Process::kill); connect(this, &MainWindow::setProcEnv, pm3, &PM3Process::setProcEnv); + connect(this, &MainWindow::setWorkingDir, pm3, &PM3Process::setWorkingDir); connect(util, &Util::write, pm3, &PM3Process::write); @@ -1160,3 +1173,10 @@ void MainWindow::on_Set_Client_envScriptEdit_editingFinished() 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(); +} diff --git a/ui/mainwindow.h b/ui/mainwindow.h index b2747c9..e0ec0a3 100644 --- a/ui/mainwindow.h +++ b/ui/mainwindow.h @@ -173,6 +173,8 @@ private slots: void on_Set_Client_envScriptEdit_editingFinished(); + void on_Set_Client_saveWorkingDirButton_clicked(); + private: Ui::MainWindow* ui; QButtonGroup* MFCardTypeBtnGroup; @@ -199,6 +201,7 @@ private: QTimer* portSearchTimer; QStringList portList; QStringList clientEnv; + QDir* clientWorkingDir; Mifare* mifare; Util* util; @@ -217,5 +220,6 @@ signals: void killPM3(); void setSerialListener(const QString& name, bool state); void setProcEnv(const QStringList *env); + void setWorkingDir(const QString& dir); }; #endif // MAINWINDOW_H diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index 5143dba..ba5bfdf 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -130,7 +130,7 @@ - 0 + 4 @@ -1538,7 +1538,7 @@ Settings - + @@ -1573,6 +1573,49 @@ then put the path of the script there + + + + Qt::Horizontal + + + + + + + Client working directory: + + + + + + + + + ../data + + + + + + + Save + + + + + + + + + Note: +On Windows, the client working directory should not be identical to the path of GUI, otherwise the client will use the wrong .dll file. + + + true + + + diff --git a/ui/mf_trailerdecoderdialog.cpp b/ui/mf_trailerdecoderdialog.cpp index fca353d..d4c5092 100644 --- a/ui/mf_trailerdecoderdialog.cpp +++ b/ui/mf_trailerdecoderdialog.cpp @@ -123,7 +123,7 @@ void MF_trailerDecoderDialog::setTableItem(QTableWidget* widget, int row, int co widget->item(row, column)->setText(text); } -void MF_trailerDecoderDialog::on_boxChanged(int arg1) +void MF_trailerDecoderDialog::on_boxChanged() { quint8 ACBits[4]; ACBits[0] = ui->C0Box->value(); diff --git a/ui/mf_trailerdecoderdialog.h b/ui/mf_trailerdecoderdialog.h index 775608a..5442ee5 100644 --- a/ui/mf_trailerdecoderdialog.h +++ b/ui/mf_trailerdecoderdialog.h @@ -27,7 +27,7 @@ private slots: void on_blockSizeChanged(int id, bool st); - void on_boxChanged(int arg1); + void on_boxChanged(); private: Ui::MF_trailerDecoderDialog *ui; QRegularExpressionValidator* validator;