36 Commits

Author SHA1 Message Date
wh201906 aee621c196 V0.2.7 2023-02-26 13:12:33 +08:00
wh201906 b788d6a15f Misc work in translation
Update translations
Fix the translation in t55xxtab
(QTranslator must be created before wigets)
Reduce unnecessary translations
2023-02-26 12:33:15 +08:00
wh201906 92d704bc96 Update README
Remove introduction of Iceman/RRG repo
(It is the default repo of this GUI now)
Update build instructions
2023-02-26 09:45:04 +08:00
wh201906 d671266797 Replace replace(xxx, "") with remove(xxx) 2023-02-26 09:43:54 +08:00
wh201906 5a26cd1936 Fix nested setting groups 2023-02-26 00:49:39 +08:00
wh201906 5b84e58ecb UI: More configurable items
Code part
Fonts, opacity and theme are configurable now
Add dark theme for night owls
2023-02-19 00:19:07 +08:00
wh201906 29bac475b5 Add QDarkStyleSheet for Dark/Light theme
Stylesheet is from https://github.com/ColinDuquesnoy/QDarkStyleSheet
2023-02-19 00:17:33 +08:00
wh201906 6926b2f170 UI: More configurable items
UI part
2023-02-18 15:25:40 +08:00
wh201906 aaf6e52a12 Add URLs for releases and reporting bugs 2023-02-14 00:40:11 +08:00
wh201906 b3001e71b7 Disable disconnection detection on Linux/macOS 2023-02-13 09:49:56 +08:00
wh201906 a7e112f124 Better Trailer Decoder
Fix the decoding of isKeyBReadable
Show every Access Bits
Show isKeyBReadable
Add comment for the decoding process
Better UI
Remove unnecessary debug output
2023-02-13 09:27:38 +08:00
wh201906 c2d3248b68 Add --force for hf mf wrbl(v4.15864)
Otherwise writing to trailer block and block 0 won't work
2023-02-12 22:57:50 +08:00
wh201906 2723abd260 Update README
Add download links from SourceForge
Remove unnecessary steps in macOS building instructions
2022-11-25 13:36:03 +08:00
wh201906 9aff432b1b Merge branch 'dev' 2022-11-25 01:27:09 +08:00
wh201906 ce973fda96 V0.2.6
Update deploy/deploy.py
2022-11-25 01:10:37 +08:00
wh201906 2704b7cfc2 Update translations 2022-11-24 23:46:11 +08:00
wh201906 2b5c94974d Add support for rrg v4.15864
Add key result as comment in config files
Specify card size in hf mf dump/restore
Use regular expression to detect lf config text
Skip the useless waiting when hf mf nested detects the static nonce then
perform staticnested attack
2022-11-24 19:44:59 +08:00
wh201906 d8d9178ce8 Fix PM3 hardware detection 2022-11-24 01:34:25 +08:00
wh201906 9c89df4519 Misc
add config file to resource system
move language folder
2022-11-24 01:24:13 +08:00
wh201906 757fdcfc21 Misc
select available PM3 hardware port when updating the serial port list
remove extra empty lines in raw command output by replacing
appendPlainText() with insertPlainText() rather than starting the client
with QProcess::Text
2022-11-23 16:51:37 +08:00
wh201906 a9b19f92d6 More hints
For serial ports which look like PM3 hardware, show a '*' behind them.
Show message box if the GUI fails to connect to the hardware
2022-11-23 15:26:28 +08:00
wh201906 b2cb1ea8e7 Show current working directory of GUI in Settings 2022-11-23 14:16:51 +08:00
wh201906 da2f6ead6e Add feedback of failing to start the client
plus, make setRequiringOutput() matched in PM3Process::connectPM3()
2022-11-23 14:01:19 +08:00
wh201906 3c6d5e4d82 Update README 2022-09-12 22:36:21 +08:00
wh201906 8105aba254 Merge pull request #33 from rzhq/macos_build
added documents for macOS build
2022-07-14 10:54:32 +08:00
rzhq ebf1980af5 added documents for macOS build 2022-07-14 11:04:41 +10:00
wh201906 fd0f9c081f Merge pull request #32 from zxkmm/master
English translate correction/更正一些英文翻译
2022-06-28 00:32:33 +08:00
wh201906 ef9972d24a Fix default lf config 2022-06-28 00:29:26 +08:00
zxkmm 8739dde6a2 Update zh_CN.ts
corrected typo
2022-06-10 18:31:51 +08:00
zxkmm 2e1e8a0ae5 Update en_US.ts
corrected typo
2022-06-10 18:31:13 +08:00
zxkmm 9b206d6828 Update mifare.cpp
corrected typo
2022-06-10 18:30:06 +08:00
zxkmm 3b1092304c Update en_US.ts 2022-06-10 18:25:43 +08:00
zxkmm 924178dffa Update zh_CN.ts
corrected typo
2022-06-10 18:24:46 +08:00
zxkmm 953e686785 Update mifare.cpp
corrected typo
2022-06-10 18:22:14 +08:00
wh201906 a2d63b5cdc Update tutorial 2022-04-03 15:55:03 +08:00
wh201906 9dcd291894 Misc
Terminate the child thread properly
Optimize write logic
2022-03-21 15:45:31 +08:00
459 changed files with 7445 additions and 1437 deletions
+24 -3
View File
@@ -2,15 +2,36 @@
[中文](doc/CHANGELOG/CHANGELOG_zh_CN.md)
### V0.2.7
+ Fix writing to Block 0 failure when using with RRG repo v4.15864
+ Disable disconnection detection on Linux/macOS by default
+ Fix a little bug in the config file
+ Fix the Trailer Decoder
+ Show more details in the Trailer Decoder
+ Add dark theme(from https://github.com/ColinDuquesnoy/QDarkStyleSheet)
+ Add support for customizable theme, opacity and fonts
+ Fix translations
### V0.2.6
+ Add support for Iceman/RRG repo v4.15864 [#37](https://github.com/wh201906/Proxmark3GUI/issues/37)
+ Optimize mifare classic block writing logic
+ Fix the default lf config
+ Add feedback for the GUI failing to start the client
+ Add feedback for the client failing to connect to PM3 hardware
+ Detect PM3 hardware when searching serial ports
+ Remove extra empty lines in raw command output
+ Use embedded config files
+ Remove the wait time between performing nested attack then switching to staticnested attack
### V0.2.5
+ Fix bug [#28](https://github.com/wh201906/Proxmark3GUI/issues/28)
+ Fix bug [#28](https://github.com/wh201906/Proxmark3GUI/issues/28)
### V0.2.4
+ Clone EM410x card to T55xx card
### V0.2.3
+ Fix bug [#27](https://github.com/wh201906/Proxmark3GUI/issues/27)
+ Try to support Non-ASCII path
+ Fix bug [#27](https://github.com/wh201906/Proxmark3GUI/issues/27)
+ Try to support Non-ASCII path
### V0.2.2
+ Load command format from external json file
+43 -20
View File
@@ -1,7 +1,10 @@
# Proxmark3GUI
![downloads](https://img.shields.io/github/downloads/wh201906/Proxmark3GUI/total)
[![downloads](https://img.shields.io/github/downloads/wh201906/Proxmark3GUI/total?label=GitHub%20release%20downloads)](https://github.com/wh201906/Proxmark3GUI/releases)
[![downloads](https://img.shields.io/sourceforge/dt/proxmark3gui.svg?label=SourceForge%20downloads)](https://sourceforge.net/projects/proxmark3gui/)
A cross-platform GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) client
A cross-platform GUI for [Proxmark3](https://github.com/Proxmark/proxmark3)/[Proxmark3 Iceman fork](https://github.com/RfidResearchGroup/proxmark3) client
(The [orignal Proxmark3 repo](https://github.com/Proxmark/proxmark3) has been unmaintained for a long time. I personally suggest using the [Proxmark3 Iceman fork](https://github.com/RfidResearchGroup/proxmark3))
[中文介绍](doc/README/README_zh_CN.md)
@@ -32,13 +35,6 @@ A cross-platform GUI for [Proxmark3](https://github.com/Proxmark/proxmark3) clie
***
## About Iceman fork/repo
The [Iceman fork/repo](https://github.com/RfidResearchGroup/proxmark3) has more powerful functions. 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.13441)
***
## About Compiled Windows clients
A cool guy [Gator96100](https://github.com/Gator96100) creates [ProxSpace](https://github.com/Gator96100/ProxSpace) and makes it possible to compile both the firmware and the client on Windows.
@@ -48,18 +44,45 @@ Great thanks to him.
***
## Build on Linux
## Download binaries for Windows
You can download pre-built Windows binaries in [release](https://github.com/wh201906/Proxmark3GUI/releases) page
`Vx.x.x-win64.7z` only contains the GUI
`Vx.x.x-win64-xxxxxxx.7z` contains the GUI and corresponding client. You just need to open `Vx.x.x-win64-xxxxxxx\GUI\Proxmark3GUI.exe`
cd ~
sudo apt-get update
sudo apt-get install qt5-default libqt5serialport5 libqt5serialport5-dev
git clone https://github.com/wh201906/Proxmark3GUI.git --depth=1
cd Proxmark3GUI
mkdir build && cd build
qmake ../src
make -j4 && make clean
cp -r ../config ./
./Proxmark3GUI
You can also download them in SourceForge
[![Download Proxmark3GUI](https://a.fsdn.com/con/app/sf-download-button)](https://sourceforge.net/projects/proxmark3gui/files/latest/download)
## Build on Linux
```
cd ~
sudo apt-get update
sudo apt-get install git build-essential
sudo apt-get install qt5-default libqt5serialport5-dev
git clone https://github.com/wh201906/Proxmark3GUI.git --depth=1
cd Proxmark3GUI
mkdir build && cd build
qmake ../src
make -j4 && make clean
./Proxmark3GUI
```
## Build on macOS
```
cd ~
brew update
brew install qt@5
brew link qt5 --force
git clone https://github.com/wh201906/Proxmark3GUI.git --depth=1
cd Proxmark3GUI
mkdir build && cd build
qmake ../src
make -j4 && make clean
open Proxmark3GUI.app
```
> In order for the GUI to connect to the device in macOS, you'd need to tweak the settings a little bit
![macOS_settings](doc/README/macOS_settings.png)
***
## Tutorial
+7
View File
@@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/config">
<file>config_official.json</file>
<file>config_rrgv4.13441.json</file>
<file>config_rrgv4.15864.json</file>
</qresource>
</RCC>
+38 -10
View File
@@ -10,6 +10,13 @@
"2k": "2",
"4k": "4"
},
"//": "|---|----------------|---|----------------|---| ",
"//": "|sec|key A |res|key B |res| ",
"//": "|---|----------------|---|----------------|---| ",
"//": "|000| ffffffffffff | 1 | ffffffffffff | 1 | ",
"//": "......",
"//": "|---|----------------|---|----------------|---| ",
"//": "",
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
"key A index": 2,
"key B index": 4
@@ -22,6 +29,15 @@
"2k": "2",
"4k": "4"
},
"//": "|---|----------------|----------------| ",
"//": "|sec|key A |key B | ",
"//": "|---|----------------|----------------| ",
"//": "|000| ffffffffffff | ffffffffffff | ",
"//": "......",
"//": "|004| ? | ? | ",
"//": "......",
"//": "|---|----------------|----------------| ",
"//": " ",
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
"key A index": 2,
"key B index": 3
@@ -39,10 +55,22 @@
"cmd": "hf list mf"
},
"dump": {
"cmd": "hf mf dump"
"cmd": "hf mf dump <card type>",
"card type": {
"mini": "0",
"1k": "1",
"2k": "2",
"4k": "4"
}
},
"restore": {
"cmd": "hf mf restore"
"cmd": "hf mf restore <card type>",
"card type": {
"mini": "0",
"1k": "1",
"2k": "2",
"4k": "4"
}
},
"emulator wipe": {
"cmd": "hf mf eclr"
@@ -192,14 +220,14 @@
"divisor cmd": "hw setlfdivisor <divisor>"
}
},
"t55xx":{
"clone em410x":{
"read":"lf search",
"successful read flag":"Valid EM410x ID",
"pattern":"EM TAG ID\\s*:\\s\\K[0-9a-fA-F]{10}",
"clone cmd":"lf em 410xwrite <id> <type>",
"t5555 flag":"0",
"t55x7 flag":"1"
"t55xx": {
"clone em410x": {
"read": "lf search",
"successful read flag": "Valid EM410x ID",
"pattern": "EM TAG ID\\s*:\\s\\K[0-9a-fA-F]{10}",
"clone cmd": "lf em 410xwrite <id> <type>",
"t5555 flag": "0",
"t55x7 flag": "1"
}
}
}
@@ -15,6 +15,13 @@
"A": "a",
"B": "b"
},
"//": "[+] |-----|----------------|---|----------------|---|",
"//": "[+] | Sec | key A |res| key B |res|",
"//": "[+] |-----|----------------|---|----------------|---|",
"//": "[+] | 000 | ffffffffffff | 1 | ffffffffffff | 1 |",
"//": "......",
"//": "[+] |-----|----------------|---|----------------|---|",
"//": "[+] ( 0:Failed / 1:Success )",
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
"key A index": 2,
"key B index": 4
@@ -27,6 +34,15 @@
"2k": "2k",
"4k": "4k"
},
"//": "[+] |-----|----------------|---|----------------|---|",
"//": "[+] | Sec | key A |res| key B |res|",
"//": "[+] |-----|----------------|---|----------------|---|",
"//": "[+] | 000 | ffffffffffff | 1 | ffffffffffff | 1 |",
"//": "......",
"//": "[+] | 004 | ------------ | 0 | ------------ | 0 |",
"//": "......",
"//": "[+] |-----|----------------|---|----------------|---|",
"//": "[+] ( 0:Failed / 1:Success )",
"key pattern": "\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|",
"key A index": 2,
"key B index": 4
@@ -44,10 +60,22 @@
"cmd": "trace list -t mf"
},
"dump": {
"cmd": "hf mf dump"
"cmd": "hf mf dump --<card type>",
"card type": {
"mini": "mini",
"1k": "1k",
"2k": "2k",
"4k": "4k"
}
},
"restore": {
"cmd": "hf mf restore"
"cmd": "hf mf restore --<card type>",
"card type": {
"mini": "mini",
"1k": "1k",
"2k": "2k",
"4k": "4k"
}
},
"emulator wipe": {
"cmd": "hf mf eclr"
@@ -200,14 +228,14 @@
"divisor cmd": "hw setlfdivisor -d <divisor>"
}
},
"t55xx":{
"clone em410x":{
"read":"lf em 410x reader",
"successful read flag":"EM 410x ID",
"pattern":"EM 410x ID\\s*\\K[0-9a-fA-F]{10}",
"clone cmd":"lf em 410x clone --id <id> <type>",
"t5555 flag":"--q5",
"t55x7 flag":""
"t55xx": {
"clone em410x": {
"read": "lf em 410x reader",
"successful read flag": "EM 410x ID",
"pattern": "EM 410x ID\\s*\\K[0-9a-fA-F]{10}",
"clone cmd": "lf em 410x clone --id <id> <type>",
"t5555 flag": "--q5",
"t55x7 flag": ""
}
}
}
+241
View File
@@ -0,0 +1,241 @@
{
"//": "Based on Proxmark3 rrg repo v4.15864, commit 1f75adc",
"//": "You can change this file if the command format of client changes",
"mifare classic": {
"nested": {
"cmd": "hf mf nested --<card type> --blk <block> -<key type> -k <key>",
"static cmd": "hf mf staticnested --<card type> --blk <block> -<key type> -k <key>",
"card type": {
"mini": "mini",
"1k": "1k",
"2k": "2k",
"4k": "4k"
},
"key type": {
"A": "a",
"B": "b"
},
"//": "[+] -----+-----+--------------+---+--------------+----",
"//": "[+] Sec | Blk | key A |res| key B |res",
"//": "[+] -----+-----+--------------+---+--------------+----",
"//": "[+] 000 | 003 | FFFFFFFFFFFF | 1 | FFFFFFFFFFFF | 1",
"//": "......",
"//": "[+] -----+-----+--------------+---+--------------+----",
"//": "[+] ( 0:Failed / 1:Success )",
"key pattern": "\\s*\\d{3}\\s*\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*$",
"key A index": 2,
"key B index": 4
},
"check": {
"cmd": "hf mf chk --<card type>",
"card type": {
"mini": "mini",
"1k": "1k",
"2k": "2k",
"4k": "4k"
},
"//": "[+] -----+-----+--------------+---+--------------+----",
"//": "[+] Sec | Blk | key A |res| key B |res",
"//": "[+] -----+-----+--------------+---+--------------+----",
"//": "[+] 000 | 003 | FFFFFFFFFFFF | 1 | FFFFFFFFFFFF | 1",
"//": "......",
"//": "[+] 004 | 019 | ------------ | 0 | ------------ | 0",
"//": "......",
"//": "[+] -----+-----+--------------+---+--------------+----",
"//": "[+] ( 0:Failed / 1:Success )",
"key pattern": "\\s*\\d{3}\\s*\\|\\s*\\d{3}\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*\\|\\s*.+?\\s*$",
"key A index": 2,
"key B index": 4
},
"info": {
"cmd": "hf 14a info"
},
"sniff": {
"cmd": "hf sniff"
},
"sniff 14a": {
"cmd": "hf 14a sniff"
},
"list": {
"cmd": "trace list -t mf"
},
"dump": {
"cmd": "hf mf dump --<card type>",
"card type": {
"mini": "mini",
"1k": "1k",
"2k": "2k",
"4k": "4k"
}
},
"restore": {
"cmd": "hf mf restore --<card type>",
"card type": {
"mini": "mini",
"1k": "1k",
"2k": "2k",
"4k": "4k"
}
},
"emulator wipe": {
"cmd": "hf mf eclr"
},
"Magic Card wipe": {
"cmd": "hf mf cwipe"
},
"emulator read block": {
"cmd": "hf mf egetblk --blk <block>",
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
},
"Magic Card read block": {
"cmd": "hf mf cgetblk --blk <block>",
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
},
"normal read block": {
"cmd": "hf mf rdbl --blk <block> -<key type> -k <key>",
"key type": {
"A": "a",
"B": "b"
},
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
},
"darkside": {
"cmd": "hf mf darkside"
},
"save sniff": {
"cmd": "trace save -f <filename>"
},
"load sniff": {
"cmd": "trace load -f <filename>",
"show cmd": "trace list --buffer -t mf"
},
"hardnested": {
"cmd": "hf mf hardnested --blk <known key block> -<known key type> -k <known key> --tblk <target key block> --t<target key type>",
"known key type": {
"A": "a",
"B": "b"
},
"target key type": {
"A": "a",
"B": "b"
}
},
"normal read sector": {
"cmd": "hf mf rdsc --sec <sector> -<key type> -k <key>",
"key type": {
"A": "a",
"B": "b"
},
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
},
"Magic Card read sector": {
"cmd": "hf mf cgetsc --sec <sector>",
"data pattern": "([0-9a-fA-F]{2} ){15}[0-9a-fA-F]{2}"
},
"//": "When writing a block, if the result is not empty and doesn't contain the failed flag, the function will return true",
"normal write block": {
"cmd": "hf mf wrbl --blk <block> -<key type> -k <key> -d <data> --force",
"key type": {
"A": "a",
"B": "b"
},
"failed flag": [
"fail",
"error"
]
},
"Magic Card write block": {
"cmd": "hf mf csetblk --blk <block> -d <data>",
"failed flag": [
"fail",
"error"
]
},
"emulator write block": {
"cmd": "hf mf esetblk --blk <block> -d <data>"
},
"Magic Card lock": {
"cmd": "hf 14a raw ",
"sequence": [
"-ak -b 7 40",
"-ak 43",
"-ak E0 00 39 F7",
"-ak E1 00 E1 EE",
"-ak 85 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 18 47",
"-a 52"
]
},
"Magic Card set parameter": {
"cmd": "hf mf csetuid --uid <uid> --atqa <atqa> --sak <sak>"
}
},
"lf": {
"read": {
"cmd": "lf read -v",
"show cmd": "data plot"
},
"sniff": {
"cmd": "lf sniff -v",
"show cmd": "data plot"
},
"search": {
"cmd": "lf search -u"
},
"tune": {
"cmd": "lf tune --divisor <divisor>"
},
"get config": {
"cmd": "hw status",
"field start": "LF Sampling config",
"field end": "\\[#\\] \\S",
"divisor": {
"flag": "divisor",
"pattern": "\\d+"
},
"bits per sample": {
"flag": "bits per sample",
"pattern": "\\d+"
},
"decimation": {
"flag": "decimation",
"pattern": "\\d+"
},
"averaging": {
"flag": "averaging",
"pattern": "\\d+",
"replace": {
"yes": "1",
"no": "0",
"Yes": "1",
"No": "0"
}
},
"trigger threshold": {
"flag": "trigger threshold",
"pattern": "\\d+"
},
"samples to skip": {
"flag": "samples to skip",
"pattern": "\\d+"
},
"//": "execute 'cmd' then find parameters between 'field stard' and 'field end'",
"//": "for each line, if the line doesn't have any flag, skip",
"//": "otherwise, delete characters before 'flag' and 'flag' itself, then use 'pattern' to get the parameter",
"//": "If 'replace' dict exists, replace all keys with respective values before getting parameters"
},
"set config": {
"cmd": "lf config --divisor <divisor> --bps <bits per sample> --dec <decimation> --avg <averaging> --trig <trigger threshold> --skip <samples to skip>",
"divisor cmd": "hw setlfdivisor -d <divisor>"
}
},
"t55xx": {
"clone em410x": {
"read": "lf em 410x reader",
"successful read flag": "EM 410x ID",
"pattern": "EM 410x ID\\s*\\K[0-9a-fA-F]{10}",
"clone cmd": "lf em 410x clone --id <id> <type>",
"t5555 flag": "--q5",
"t55x7 flag": ""
}
}
}
+45 -22
View File
@@ -1,17 +1,19 @@
import os, sys, shutil
from win32api import GetFileVersionInfo
from json import load
from re import fullmatch, IGNORECASE
from re import fullmatch, sub, IGNORECASE
compressDirList = []
def getPEVersion(fname):
try:
fileInfo = GetFileVersionInfo(fname, '\\')
version = "V%d.%d.%d" % (fileInfo['FileVersionMS'] / 65536,
fileInfo['FileVersionMS'] % 65536,
fileInfo['FileVersionLS'] / 65536)
fileInfo = GetFileVersionInfo(fname, "\\")
version = "V%d.%d.%d" % (
fileInfo["FileVersionMS"] / 65536,
fileInfo["FileVersionMS"] % 65536,
fileInfo["FileVersionLS"] / 65536,
)
except Exception:
print("Cannot get version number of", fname)
return version
@@ -19,7 +21,7 @@ def getPEVersion(fname):
os.chdir(sys.path[0])
print("Current Directory:", os.getcwd())
targetName = os.path.abspath(os.getcwd()).split('\\')[-2]
targetName = os.path.abspath(os.getcwd()).split("\\")[-2]
print("Target Name", targetName)
src32Dir = ""
@@ -63,11 +65,6 @@ elif not os.path.exists(dst32Dir):
print(dst32Dir, "doesn't exist, creating...")
shutil.copytree("./32", dst32Dir)
shutil.copyfile(src32Path, dst32Path)
configPath = dst32Dir + "/config"
if os.path.exists(configPath):
print(configPath, "exists, replacing...")
shutil.rmtree(configPath)
shutil.copytree("../config", configPath)
compressDirList.append(dst32Dir)
if os.path.exists(dst64Dir) and os.path.exists(dst64Path):
@@ -77,19 +74,23 @@ elif not os.path.exists(dst64Dir):
print(dst64Dir, "doesn't exist, creating...")
shutil.copytree("./64", dst64Dir)
shutil.copyfile(src64Path, dst64Path)
configPath = dst64Dir + "/config"
if os.path.exists(configPath):
print(configPath, "exists, replacing...")
shutil.rmtree(configPath)
shutil.copytree("../config", configPath)
compressDirList.append(dst64Dir)
# TODO: GUI+client
clientList = [
"official-v3.1.0", "rrg_other-v4.13441", "rrg_other-v4.14434",
"rrg_other-v4.14831"
"official-v3.1.0",
"rrg_other-v4.13441",
"rrg_other-v4.14434",
"rrg_other-v4.14831",
"rrg_other-v4.15864",
]
configList = []
for config in os.listdir("../config"):
configPath = os.path.join("../config", config)
if os.path.isfile(configPath) and config.endswith(".json"):
configList.append(config)
def generateClient(clientName):
global compressDirList
@@ -105,12 +106,34 @@ def generateClient(clientName):
shutil.copytree(clientSrcDir, clientDstDir)
shutil.copytree(dst64Dir, clientDstGUIDir)
if "official" in clientName:
shutil.copyfile("./client/GUIsettings_Official.ini",
clientDstGUIDir + "/GUIsettings.ini")
shutil.copyfile(
"./client/GUIsettings_Official.ini", clientDstGUIDir + "/GUIsettings.ini"
)
elif "rrg" in clientName:
shutil.copyfile("./client/GUIsettings_RRG.ini",
clientDstGUIDir + "/GUIsettings.ini")
shutil.copyfile(
"./client/GUIsettings_RRG.ini", clientDstGUIDir + "/GUIsettings.ini"
)
# Use exactly matched configFile if possible
version = clientName[clientName.find("v") :]
for config in configList:
if version in config:
print("Find matched config file", config)
with open(
clientDstGUIDir + "/GUIsettings.ini", "r", encoding="utf-8"
) as f:
data = f.read()
data = sub(
"configFile=:/config/.+\\.json",
"configFile=:/config/" + config,
data,
)
with open(
clientDstGUIDir + "/GUIsettings.ini", "w", encoding="utf-8"
) as f:
f.write(data)
compressDirList.append(clientDstDir)
return clientDstDir
for cl in clientList:
+21
View File
@@ -2,6 +2,27 @@
[English](../../CHANGELOG.md)
### V0.2.7
+ 修复使用冰人版v4.15864时无法写入块0的问题
+ 默认关闭Linux/macOS系统下对PM3硬件断连的检测
+ 修复配置文件中的小Bug
+ 修复访问控制位解码器
+ 在访问控制位解码器中显示更多细节
+ 添加暗黑主题(源于https://github.com/ColinDuquesnoy/QDarkStyleSheet)
+ 支持自定义主题,透明度,字体
+ 修复若干翻译问题
### V0.2.6
+ 支持冰人版客户端 v4.15864 [#37](https://github.com/wh201906/Proxmark3GUI/issues/37)
+ 优化Mifare Classic卡写卡逻辑
+ 修复lf config默认配置
+ 添加客户端无法启动的提示
+ 添加PM3硬件连接失败的提示
+ 为PM3对应串口添加提示,并自动选中
+ 修复原始指令框中有多余空行的问题
+ 内嵌不同客户端的配置文件
+ 去除从nested attack切换到staticnested attack的等待时间
### V0.2.5
+ 修复 [#28](https://github.com/wh201906/Proxmark3GUI/issues/28)
+44 -20
View File
@@ -1,7 +1,10 @@
# Proxmark3GUI
![downloads](https://img.shields.io/github/downloads/wh201906/Proxmark3GUI/total)
[![downloads](https://img.shields.io/github/downloads/wh201906/Proxmark3GUI/total?label=GitHub%E4%B8%8B%E8%BD%BD%E9%87%8F)](https://github.com/wh201906/Proxmark3GUI/releases)
[![downloads](https://img.shields.io/sourceforge/dt/proxmark3gui.svg?label=SourceForge%E4%B8%8B%E8%BD%BD%E9%87%8F)](https://sourceforge.net/projects/proxmark3gui/)
一个自制的[Proxmark3](https://github.com/Proxmark/proxmark3) GUI,可在Windows/Linux系统下运行
一个自制的[Proxmark3](https://github.com/Proxmark/proxmark3) GUI,可在Windows/Linux/macOS系统下运行,支持[官方版](https://github.com/Proxmark/proxmark3)/[冰人版](https://github.com/RfidResearchGroup/proxmark3)客户端和固件
(目前[官方版](https://github.com/Proxmark/proxmark3)已停更超过一年,推荐使用[冰人版](https://github.com/RfidResearchGroup/proxmark3)固件和客户端)
[English](../../README.md)
@@ -28,13 +31,7 @@
## 预览图
![preview](preview_zh_CN.png)
[更多预览](../preview/previews.md)
***
## 关于冰人版
[冰人版](https://github.com/RfidResearchGroup/proxmark3)(Iceman/RRG)的客户端和固件更新更为激进,相比官方版具有更多的功能
此GUI所有功能均兼容冰人版(在v4.13441上测试通过)
[更多预览](../preview/previews.md)
***
@@ -47,18 +44,45 @@ release页面中有含客户端的GUI。这个GUI也可以搭配你自己的客
***
## 在Linux系统下编译
## 下载Windows版本
[release](https://github.com/wh201906/Proxmark3GUI/releases) 页面当中包含了编译好的Windows程序,解压后即可使用
`Vx.x.x-win64.7z`是不带客户端的纯GUI程序,可配合已有的客户端使用
`Vx.x.x-win64-xxxxxxx.7z`包含了对应的客户端,打开`Vx.x.x-win64-xxxxxxx\GUI\Proxmark3GUI.exe`即可使用
cd ~
sudo apt-get update
sudo apt-get install qt5-default libqt5serialport5 libqt5serialport5-dev
git clone https://github.com/wh201906/Proxmark3GUI.git --depth=1
cd Proxmark3GUI
mkdir build && cd build
qmake ../src
make -j4 && make clean
cp -r ../config ./
./Proxmark3GUI
SourceForge平台上也可下载
[![Download Proxmark3GUI](https://a.fsdn.com/con/app/sf-download-button)](https://sourceforge.net/projects/proxmark3gui/files/latest/download)
## 在Linux系统下编译
```
cd ~
sudo apt-get update
sudo apt-get install git build-essential
sudo apt-get install qt5-default libqt5serialport5-dev
git clone https://github.com/wh201906/Proxmark3GUI.git --depth=1
cd Proxmark3GUI
mkdir build && cd build
qmake ../src
make -j4 && make clean
./Proxmark3GUI
```
## 在macOS系统下编译
```
cd ~
brew update
brew install qt@5
brew link qt5 --force
git clone https://github.com/wh201906/Proxmark3GUI.git --depth=1
cd Proxmark3GUI
mkdir build && cd build
qmake ../src
make -j4 && make clean
open Proxmark3GUI.app
```
> 为使GUI在macOS下正确连接设备,需要更改一些设置
![macOS_settings](macOS_settings.png)
***
## 教程
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

+23 -2
View File
@@ -41,5 +41,26 @@
(3) You might need to change "\<port\>" to "/dev/\<port\>" in "Settings"->"Start arguments" editbox
![](args_linux.png)
(4) If you are using Raspbian(Raspberry OS), you might need to check "Keep the client active even the PM3 hardware is disconnected." in the "Steeings" panel
![](keep.png)
(4) If you are using Raspbian(Raspberry OS), you might need to check "Keep the client active even the PM3 hardware is disconnected." in the "Settings" panel
![](keep.png)
## About preload script
The client might refer to some environment variables to load dependencies
For example, the RRG client on Windows requires these environment variables
```
QT_PLUGIN_PATH=<client path>\libs\
QT_QPA_PLATFORM_PLUGIN_PATH=<client path>\libs\
PATH=<client path>\libs\;<client path>\libs\shell\;<old PATH variable>
MSYSTEM=MINGW64
```
So the GUI will run "\<client path\>\\setup.bat" before loading the client, which will set the environment variables to the client properly. The script will not affect the system environment variables.
The contents of setup.bat are as follows
```
@echo off
set "HOME=%~dp0"
set "QT_PLUGIN_PATH=%HOME%\libs\"
set "QT_QPA_PLATFORM_PLUGIN_PATH=%QT_PLUGIN_PATH%"
set "PATH=%QT_PLUGIN_PATH%;%QT_PLUGIN_PATH%shell\;%PATH%"
set MSYSTEM=MINGW64
```
You can write your own script by referring to it if you need other client, then input the script path in the "Preload script path" editbox.
+23 -1
View File
@@ -46,4 +46,26 @@
![](args_linux_zh_CN.png)
(4) 若使用树莓派Raspbian系统且连接成功若干秒后PM3会自动断开,则需要在“设置”面板中勾选“在PM3断开后保持客户端运行”
![](keep_zh_CN.png)
![](keep_zh_CN.png)
## 预加载脚本
客户端在运行时可能需要使用某些环境变量以解决依赖问题
例如,Windows平台下的冰人客户端运行时需要以下环境变量
```
QT_PLUGIN_PATH=<客户端路径>\libs\
QT_QPA_PLATFORM_PLUGIN_PATH=<客户端路径>\libs\
PATH=<客户端路径>\libs\;<客户端路径>\libs\shell\;<原PATH变量>
MSYSTEM=MINGW64
```
因此,GUI会在加载客户端之前先运行"\<客户端路径\>\\setup.bat",从而在加载客户端时使用正确的环境变量。这些设置不会影响系统环境变量,仅对客户端本身有效
setup.bat的内容如下
```
@echo off
set "HOME=%~dp0"
set "QT_PLUGIN_PATH=%HOME%\libs\"
set "QT_QPA_PLATFORM_PLUGIN_PATH=%QT_PLUGIN_PATH%"
set "PATH=%QT_PLUGIN_PATH%;%QT_PLUGIN_PATH%shell\;%PATH%"
set MSYSTEM=MINGW64
```
如果需要使用其它客户端,你可以参考此文件编写自己的脚本,然后将其填入“预加载脚本路径”当中
BIN
View File
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,3 @@
[Languages]
en_US=English
zh_CN=简体中文
ext=Load from external file
Binary file not shown.
File diff suppressed because it is too large Load Diff
+7 -4
View File
@@ -51,18 +51,21 @@ FORMS += \
ui/mf_attack_hardnesteddialog.ui
TRANSLATIONS += \
i18n/zh_CN.ts \
i18n/en_US.ts
../i18n/zh_CN.ts \
../i18n/en_US.ts
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
VERSION = 0.2.5
VERSION = 0.2.7
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
QMAKE_TARGET_COMPANY = "wh201906"
RESOURCES += \
i18n/language.qrc
../i18n/language.qrc \
../config/config.qrc \
qdarkstyle/dark/darkstyle.qrc \
qdarkstyle/light/lightstyle.qrc
+9 -1
View File
@@ -13,6 +13,8 @@ PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent)
connect(serialListener, &QTimer::timeout, this, &PM3Process::onTimeout);
connect(this, &PM3Process::readyRead, this, &PM3Process::onReadyRead);
portInfo = nullptr;
qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
}
void PM3Process::connectPM3(const QString& path, const QStringList args)
@@ -26,7 +28,8 @@ void PM3Process::connectPM3(const QString& path, const QStringList args)
currArgs = args;
// using "-f" option to make the client output flushed after every print.
start(path, args, QProcess::Unbuffered | QProcess::ReadWrite | QProcess::Text);
// single '\r' might appear. Don't use QProcess::Text there or '\r' is ignored.
start(path, args, QProcess::Unbuffered | QProcess::ReadWrite);
if(waitForStarted(10000))
{
waitForReadyRead(10000);
@@ -59,8 +62,13 @@ void PM3Process::connectPM3(const QString& path, const QStringList args)
emit PM3StatedChanged(true, result);
}
else
{
emit HWConnectFailed();
kill();
}
}
setRequiringOutput(false);
}
void PM3Process::reconnectPM3()
+1
View File
@@ -48,6 +48,7 @@ signals:
void PM3StatedChanged(bool st, const QString& info = "");
void newOutput(const QString& output);
void changeClientType(Util::ClientType);
void HWConnectFailed();
};
#endif // PM3PROCESS_H
+17 -5
View File
@@ -119,17 +119,29 @@ bool Util::chooseLanguage(QSettings* guiSettings, QMainWindow* window)
QStringList langList = langSettings->allKeys();
for(int i = 0; i < langList.size(); i++)
langMap.insert(langSettings->value(langList[i]).toString(), langList[i]);
langMap.insert(tr("Load from external file"), "(ext)");
langSettings->endGroup();
delete langSettings;
bool isOk = false;
QString selectedText = QInputDialog::getItem(window, "", "Choose a language:", langMap.keys(), 0, false, &isOk);
if(isOk)
QString selectedText = QInputDialog::getItem(window, "", tr("Choose a language:"), langMap.keys(), 0, false, &isOk);
if(!isOk)
return false;
if(langMap[selectedText] == "(ext)")
{
guiSettings->beginGroup("lang");
guiSettings->setValue("language", langMap[selectedText]);
QString extPath = QFileDialog::getOpenFileName(window, tr("Select the translation file:"));
if(extPath.isEmpty())
return false;
guiSettings->beginGroup("language");
guiSettings->setValue("extPath", extPath);
guiSettings->endGroup();
guiSettings->sync();
}
guiSettings->beginGroup("language");
guiSettings->setValue("name", langMap[selectedText]);
guiSettings->endGroup();
guiSettings->sync();
return isOk;
}
+2 -1
View File
@@ -13,6 +13,7 @@
#include <QSettings>
#include <QMainWindow>
#include <QInputDialog>
#include <QFileDialog>
#include <QDockWidget>
#include "ui_mainwindow.h"
@@ -58,7 +59,7 @@ public:
static ClientType getClientType();
static int rawTabIndex;
static QDockWidget* rawDockPtr;
static bool chooseLanguage(QSettings *guiSettings, QMainWindow *window);
static bool chooseLanguage(QSettings *guiSettings, QMainWindow *window = nullptr);
public slots:
void processOutput(const QString& output);
static void setClientType(Util::ClientType clientType);
BIN
View File
Binary file not shown.
+50 -16
View File
@@ -23,38 +23,72 @@ int main(int argc, char *argv[])
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
QApplication a(argc, argv);
MainWindow w;
QSettings* settings = new QSettings("GUIsettings.ini", QSettings::IniFormat);
settings->setIniCodec("UTF-8");
settings->beginGroup("lang");
QString currLang = settings->value("language", "").toString();
settings->beginGroup("language");
QString languageFile = settings->value("extPath").toString();
QString languageName = settings->value("name").toString();
settings->endGroup();
if(currLang == "")
settings->beginGroup("UI");
QString theme = settings->value("Theme_Name").toString();
settings->endGroup();
if(languageName == "")
{
if(Util::chooseLanguage(settings, &w))
if(Util::chooseLanguage(settings))
{
settings->beginGroup("lang");
currLang = settings->value("language", "").toString();
settings->beginGroup("language");
languageName = settings->value("name").toString();
settings->endGroup();
}
else
currLang = "en_US";
languageName = "en_US";
}
if(currLang == "ext")
currLang = QFileDialog::getOpenFileName(nullptr, "Select the translation file:");
else
currLang = ":/i18n/" + currLang + ".qm";
QTranslator* translator = new QTranslator(&w);
if(translator->load(currLang))
if(languageName == "(ext)")
{
settings->beginGroup("language");
languageFile = settings->value("extPath").toString();
settings->endGroup();
}
else
languageFile = ":/i18n/" + languageName + ".qm";
// Note that the translator must be created before the application's widgets.
QTranslator* translator = new QTranslator();
if(translator->load(languageFile))
a.installTranslator(translator);
}
else
QMessageBox::information(nullptr, "Error", "Can't load " + languageFile + " as translation file.");
QFile* themeFile = new QFile();
QTextStream* themeStream = new QTextStream();
QString qssString = a.styleSheet(); // default behavior
if(theme == "(none)")
;
else if(theme == "qdss_dark")
{
QMessageBox::information(&w, "Error", "Can't load " + currLang + " as translation file.");
themeFile->setFileName(":/qdarkstyle/dark/darkstyle.qss");
themeFile->open(QFile::ReadOnly | QFile::Text);
themeStream->setDevice(themeFile);
qssString = themeStream->readAll();
}
else if(theme == "qdss_light")
{
themeFile->setFileName(":/qdarkstyle/light/lightstyle.qss");
themeFile->open(QFile::ReadOnly | QFile::Text);
themeStream->setDevice(themeFile);
qssString = themeStream->readAll();
}
a.setStyleSheet(qssString);
delete themeFile;
delete themeStream;
themeFile = nullptr;
themeStream = nullptr;
delete settings;
settings = nullptr;
MainWindow w;
w.initUI();
w.show();
return a.exec();
+4 -2
View File
@@ -81,8 +81,10 @@ void LF::getLFConfig()
QVariantMap config = configMap["get config"].toMap();
QString cmd = config["cmd"].toString();
result = util->execCMDWithOutput(cmd, 400);
start = result.indexOf(config["field start"].toString());
end = result.indexOf(config["field end"].toString());
reMatch = QRegularExpression(config["field start"].toString(), QRegularExpression::MultilineOption).match(result);
start = reMatch.hasMatch() ? reMatch.capturedEnd() : 0;
reMatch = QRegularExpression(config["field end"].toString(), QRegularExpression::MultilineOption).match(result, start);
end = reMatch.hasMatch() ? reMatch.capturedStart() : result.length();
result = result.mid(start, end - start);
#if (QT_VERSION <= QT_VERSION_CHECK(5,14,0))
resultList = result.split("\n", QString::SkipEmptyParts);
+56 -36
View File
@@ -40,36 +40,39 @@ const Mifare::CardType Mifare::card_4k =
const Mifare::AccessType Mifare::dataCondition[8][4] =
{
{ACC_KEY_AB, ACC_KEY_AB, ACC_KEY_AB, ACC_KEY_AB},
{ACC_KEY_AB, ACC_KEY_B, ACC_NEVER, ACC_NEVER},
{ACC_KEY_AB, ACC_NEVER, ACC_NEVER, ACC_NEVER},
{ACC_KEY_AB, ACC_KEY_B, ACC_KEY_B, ACC_KEY_AB},
{ACC_KEY_AB, ACC_NEVER, ACC_NEVER, ACC_KEY_AB},
{ACC_KEY_B, ACC_NEVER, ACC_NEVER, ACC_NEVER},
{ACC_KEY_B, ACC_KEY_B, ACC_NEVER, ACC_NEVER},
{ACC_NEVER, ACC_NEVER, ACC_NEVER, ACC_NEVER},
// {read, write, increment, decrement/transfer/restore}
{ACC_KEY_AB, ACC_KEY_AB, ACC_KEY_AB, ACC_KEY_AB}, // {C3x, C2x, C1x} = 0
{ACC_KEY_AB, ACC_KEY_B, ACC_NEVER, ACC_NEVER}, // {C3x, C2x, C1x} = 1
{ACC_KEY_AB, ACC_NEVER, ACC_NEVER, ACC_NEVER}, // {C3x, C2x, C1x} = 2
{ACC_KEY_AB, ACC_KEY_B, ACC_KEY_B, ACC_KEY_AB}, // {C3x, C2x, C1x} = 3
{ACC_KEY_AB, ACC_NEVER, ACC_NEVER, ACC_KEY_AB}, // {C3x, C2x, C1x} = 4
{ACC_KEY_B, ACC_NEVER, ACC_NEVER, ACC_NEVER}, // {C3x, C2x, C1x} = 5
{ACC_KEY_B, ACC_KEY_B, ACC_NEVER, ACC_NEVER}, // {C3x, C2x, C1x} = 6
{ACC_NEVER, ACC_NEVER, ACC_NEVER, ACC_NEVER}, // {C3x, C2x, C1x} = 7
};
const Mifare::AccessType Mifare::trailerReadCondition[8][3] =
{
{ACC_NEVER, ACC_KEY_A, ACC_KEY_A},
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER},
{ACC_NEVER, ACC_KEY_A, ACC_KEY_A},
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER},
{ACC_NEVER, ACC_KEY_A, ACC_KEY_A},
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER},
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER},
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER},
// {KEYA, Access bits, KEYB}
{ACC_NEVER, ACC_KEY_A, ACC_KEY_A}, // {C33, C23, C13} = 0
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, // {C33, C23, C13} = 1
{ACC_NEVER, ACC_KEY_A, ACC_KEY_A}, // {C33, C23, C13} = 2
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, // {C33, C23, C13} = 3
{ACC_NEVER, ACC_KEY_A, ACC_KEY_A}, // {C33, C23, C13} = 4
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, // {C33, C23, C13} = 5
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, // {C33, C23, C13} = 6
{ACC_NEVER, ACC_KEY_AB, ACC_NEVER}, // {C33, C23, C13} = 7
};
const Mifare::AccessType Mifare::trailerWriteCondition[8][3] =
{
{ACC_KEY_A, ACC_NEVER, ACC_KEY_A},
{ACC_KEY_B, ACC_NEVER, ACC_KEY_B},
{ACC_NEVER, ACC_NEVER, ACC_NEVER},
{ACC_NEVER, ACC_NEVER, ACC_NEVER},
{ACC_KEY_A, ACC_KEY_A, ACC_KEY_A},
{ACC_NEVER, ACC_KEY_B, ACC_NEVER},
{ACC_KEY_B, ACC_KEY_B, ACC_KEY_B},
{ACC_NEVER, ACC_NEVER, ACC_NEVER},
// {KEYA, Access bits, KEYB}
{ACC_KEY_A, ACC_NEVER, ACC_KEY_A}, // {C33, C23, C13} = 0
{ACC_KEY_B, ACC_NEVER, ACC_KEY_B}, // {C33, C23, C13} = 1
{ACC_NEVER, ACC_NEVER, ACC_NEVER}, // {C33, C23, C13} = 2
{ACC_NEVER, ACC_NEVER, ACC_NEVER}, // {C33, C23, C13} = 3
{ACC_KEY_A, ACC_KEY_A, ACC_KEY_A}, // {C33, C23, C13} = 4
{ACC_NEVER, ACC_KEY_B, ACC_NEVER}, // {C33, C23, C13} = 5
{ACC_KEY_B, ACC_KEY_B, ACC_KEY_B}, // {C33, C23, C13} = 6
{ACC_NEVER, ACC_NEVER, ACC_NEVER}, // {C33, C23, C13} = 7
};
Mifare::Mifare(Ui::MainWindow *ui, Util *addr, QWidget *parent): QObject(parent)
@@ -105,11 +108,11 @@ QMap<QString, QString> Mifare::info(bool isRequiringOutput)
for(auto line = lineList.begin(); line != lineList.end(); line++)
{
if(line->contains("UID"))
map["UID"] = line->replace("UID", "").replace(QRegularExpression("[^0-9a-fA-F]"), "").trimmed();
map["UID"] = line->remove("UID").remove(QRegularExpression("[^0-9a-fA-F]")).trimmed();
else if(line->contains("ATQA"))
map["ATQA"] = line->replace("ATQA", "").replace(QRegularExpression("[^0-9a-fA-F]"), "").trimmed();
map["ATQA"] = line->remove("ATQA").remove(QRegularExpression("[^0-9a-fA-F]")).trimmed();
else if(line->contains("SAK"))
map["SAK"] = line->replace("SAK", "").replace(QRegularExpression("\\[.+?\\]"), "").replace(QRegularExpression("[^0-9a-fA-F]"), "").trimmed();
map["SAK"] = line->remove("SAK").remove(QRegularExpression("\\[.+?\\]")).remove(QRegularExpression("[^0-9a-fA-F]")).trimmed();
}
}
else
@@ -130,7 +133,7 @@ void Mifare::chk()
QString cmd = config["cmd"].toString();
int keyAindex = config["key A index"].toInt();
int keyBindex = config["key B index"].toInt();
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString());
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString(), QRegularExpression::MultilineOption);
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
result = util->execCMDWithOutput(
@@ -169,7 +172,7 @@ void Mifare::nested(bool isStaticNested)
cmd = config["cmd"].toString();
int keyAindex = config["key A index"].toInt();
int keyBindex = config["key B index"].toInt();
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString());
QRegularExpression keyPattern = QRegularExpression(config["key pattern"].toString(), QRegularExpression::MultilineOption);
QRegularExpressionMatch reMatch;
QString result;
int offset = 0;
@@ -212,7 +215,7 @@ void Mifare::nested(bool isStaticNested)
}
result = util->execCMDWithOutput(
cmd,
Util::ReturnTrigger(15000, {"Can't found", "Can't authenticate", keyPattern_res->pattern()}),
Util::ReturnTrigger(15000, {"Quit", "Can't found", "Can't authenticate", keyPattern_res->pattern()}),
true);
if(result.contains("static") && !isStaticNested)
@@ -639,7 +642,7 @@ void Mifare::writeOne(TargetType targetType)
bool isSuccessful = _writeblk(blockId, keyType, ui->MF_RW_keyEdit->text().toUpper(), ui->MF_RW_dataEdit->text(), targetType);
if(isSuccessful)
{
QMessageBox::information(parent, tr("Info"), tr("Success!"));
QMessageBox::information(parent, tr("Info"), tr("Succeed!"));
}
else
{
@@ -691,10 +694,14 @@ void Mifare::writeSelected(TargetType targetType)
{
result = _writeblk(item, KEY_B, keyBList->at(data_b2s(item)), dataList->at(item), TARGET_MIFARE);
}
if(!result)
if(!result && keyAList->at(data_b2s(item)) != "FFFFFFFFFFFF")
{
result = _writeblk(item, KEY_A, "FFFFFFFFFFFF", dataList->at(item), TARGET_MIFARE);
}
if(!result && keyBList->at(data_b2s(item)) != "FFFFFFFFFFFF") // for access bits like "80 f7 87", the block can only be written with keyB
{
result = _writeblk(item, KEY_B, "FFFFFFFFFFFF", dataList->at(item), TARGET_MIFARE);
}
}
else // key doesn't matter when writing to Chinese Magic Card and Emulator Memory
{
@@ -706,7 +713,7 @@ void Mifare::writeSelected(TargetType targetType)
}
}
if(failedBlocks.size() == 0)
QMessageBox::information(parent, tr("Info"), tr("Successful!"));
QMessageBox::information(parent, tr("Info"), tr("Succeed!"));
else
{
QString suffix = "";
@@ -743,14 +750,20 @@ void Mifare::writeSelected(TargetType targetType)
void Mifare::dump()
{
QVariantMap config = configMap["dump"].toMap();
util->execCMD(config["cmd"].toString());
QString cmd = config["cmd"].toString();
if(cmd.contains("<card type>"))
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
util->execCMD(cmd);
Util::gotoRawTab();
}
void Mifare::restore()
{
QVariantMap config = configMap["restore"].toMap();
util->execCMD(config["cmd"].toString());
QString cmd = config["cmd"].toString();
if(cmd.contains("<card type>"))
cmd.replace("<card type>", config["card type"].toMap()[cardType.typeText].toString());
util->execCMD(cmd);
Util::gotoRawTab();
}
@@ -1302,9 +1315,13 @@ bool Mifare::data_isACBitsValid(const QString& text, QList<quint8>* returnHalfBy
QList<quint8> halfBytes;
for(int i = 0; i < 6; i++)
{
// 6 7 8
// AB CD EF->
// {0xA, 0xB, 0xC, 0xD, 0xE, 0xF}
// {~C2x, ~C1x, C1x, ~C3x, C3, C2}
halfBytes.append((val >> ((5 - i) * 4)) & 0xf);
}
qDebug() << val;
// qDebug() << val;
if((~halfBytes[0] & 0xf) == halfBytes[5] && (~halfBytes[1] & 0xf) == halfBytes[2] && (~halfBytes[3] & 0xf) == halfBytes[4])
{
if(returnHalfBytes != nullptr)
@@ -1320,9 +1337,12 @@ QList<quint8> Mifare::data_getACBits(const QString& text) //return empty QList i
QList<quint8> halfBytes, result;
if(data_isACBitsValid(text, &halfBytes))
{
// data in halfbits:
// {~C2x, ~C1x, C1x, ~C3x, C3, C2}
for(int i = 0; i < 4; i++)
{
result.append((((halfBytes[4] >> i) & 1) << 2) | (((halfBytes[5] >> i) & 1) << 1) | (((halfBytes[2] >> i) & 1) << 0));
// {Cx0, Cx1, Cx2, Cx3} (Cx0={C30, C20, C10})
}
}
return result;
+1
View File
@@ -0,0 +1 @@
From commit 6ff5fdf of [QDarkStyleSheet](https://github.com/ColinDuquesnoy/QDarkStyleSheet)
+216
View File
@@ -0,0 +1,216 @@
<RCC warning="WARNING! File created programmatically. All changes made in this file will be lost!">
<qresource prefix="qss_icons/dark">
<file>rc/arrow_down.png</file>
<file>rc/arrow_down@2x.png</file>
<file>rc/arrow_down_disabled.png</file>
<file>rc/arrow_down_disabled@2x.png</file>
<file>rc/arrow_down_focus.png</file>
<file>rc/arrow_down_focus@2x.png</file>
<file>rc/arrow_down_pressed.png</file>
<file>rc/arrow_down_pressed@2x.png</file>
<file>rc/arrow_left.png</file>
<file>rc/arrow_left@2x.png</file>
<file>rc/arrow_left_disabled.png</file>
<file>rc/arrow_left_disabled@2x.png</file>
<file>rc/arrow_left_focus.png</file>
<file>rc/arrow_left_focus@2x.png</file>
<file>rc/arrow_left_pressed.png</file>
<file>rc/arrow_left_pressed@2x.png</file>
<file>rc/arrow_right.png</file>
<file>rc/arrow_right@2x.png</file>
<file>rc/arrow_right_disabled.png</file>
<file>rc/arrow_right_disabled@2x.png</file>
<file>rc/arrow_right_focus.png</file>
<file>rc/arrow_right_focus@2x.png</file>
<file>rc/arrow_right_pressed.png</file>
<file>rc/arrow_right_pressed@2x.png</file>
<file>rc/arrow_up.png</file>
<file>rc/arrow_up@2x.png</file>
<file>rc/arrow_up_disabled.png</file>
<file>rc/arrow_up_disabled@2x.png</file>
<file>rc/arrow_up_focus.png</file>
<file>rc/arrow_up_focus@2x.png</file>
<file>rc/arrow_up_pressed.png</file>
<file>rc/arrow_up_pressed@2x.png</file>
<file>rc/base_icon.png</file>
<file>rc/base_icon@2x.png</file>
<file>rc/base_icon_disabled.png</file>
<file>rc/base_icon_disabled@2x.png</file>
<file>rc/base_icon_focus.png</file>
<file>rc/base_icon_focus@2x.png</file>
<file>rc/base_icon_pressed.png</file>
<file>rc/base_icon_pressed@2x.png</file>
<file>rc/branch_closed.png</file>
<file>rc/branch_closed@2x.png</file>
<file>rc/branch_closed_disabled.png</file>
<file>rc/branch_closed_disabled@2x.png</file>
<file>rc/branch_closed_focus.png</file>
<file>rc/branch_closed_focus@2x.png</file>
<file>rc/branch_closed_pressed.png</file>
<file>rc/branch_closed_pressed@2x.png</file>
<file>rc/branch_end.png</file>
<file>rc/branch_end@2x.png</file>
<file>rc/branch_end_disabled.png</file>
<file>rc/branch_end_disabled@2x.png</file>
<file>rc/branch_end_focus.png</file>
<file>rc/branch_end_focus@2x.png</file>
<file>rc/branch_end_pressed.png</file>
<file>rc/branch_end_pressed@2x.png</file>
<file>rc/branch_line.png</file>
<file>rc/branch_line@2x.png</file>
<file>rc/branch_line_disabled.png</file>
<file>rc/branch_line_disabled@2x.png</file>
<file>rc/branch_line_focus.png</file>
<file>rc/branch_line_focus@2x.png</file>
<file>rc/branch_line_pressed.png</file>
<file>rc/branch_line_pressed@2x.png</file>
<file>rc/branch_more.png</file>
<file>rc/branch_more@2x.png</file>
<file>rc/branch_more_disabled.png</file>
<file>rc/branch_more_disabled@2x.png</file>
<file>rc/branch_more_focus.png</file>
<file>rc/branch_more_focus@2x.png</file>
<file>rc/branch_more_pressed.png</file>
<file>rc/branch_more_pressed@2x.png</file>
<file>rc/branch_open.png</file>
<file>rc/branch_open@2x.png</file>
<file>rc/branch_open_disabled.png</file>
<file>rc/branch_open_disabled@2x.png</file>
<file>rc/branch_open_focus.png</file>
<file>rc/branch_open_focus@2x.png</file>
<file>rc/branch_open_pressed.png</file>
<file>rc/branch_open_pressed@2x.png</file>
<file>rc/checkbox_checked.png</file>
<file>rc/checkbox_checked@2x.png</file>
<file>rc/checkbox_checked_disabled.png</file>
<file>rc/checkbox_checked_disabled@2x.png</file>
<file>rc/checkbox_checked_focus.png</file>
<file>rc/checkbox_checked_focus@2x.png</file>
<file>rc/checkbox_checked_pressed.png</file>
<file>rc/checkbox_checked_pressed@2x.png</file>
<file>rc/checkbox_indeterminate.png</file>
<file>rc/checkbox_indeterminate@2x.png</file>
<file>rc/checkbox_indeterminate_disabled.png</file>
<file>rc/checkbox_indeterminate_disabled@2x.png</file>
<file>rc/checkbox_indeterminate_focus.png</file>
<file>rc/checkbox_indeterminate_focus@2x.png</file>
<file>rc/checkbox_indeterminate_pressed.png</file>
<file>rc/checkbox_indeterminate_pressed@2x.png</file>
<file>rc/checkbox_unchecked.png</file>
<file>rc/checkbox_unchecked@2x.png</file>
<file>rc/checkbox_unchecked_disabled.png</file>
<file>rc/checkbox_unchecked_disabled@2x.png</file>
<file>rc/checkbox_unchecked_focus.png</file>
<file>rc/checkbox_unchecked_focus@2x.png</file>
<file>rc/checkbox_unchecked_pressed.png</file>
<file>rc/checkbox_unchecked_pressed@2x.png</file>
<file>rc/line_horizontal.png</file>
<file>rc/line_horizontal@2x.png</file>
<file>rc/line_horizontal_disabled.png</file>
<file>rc/line_horizontal_disabled@2x.png</file>
<file>rc/line_horizontal_focus.png</file>
<file>rc/line_horizontal_focus@2x.png</file>
<file>rc/line_horizontal_pressed.png</file>
<file>rc/line_horizontal_pressed@2x.png</file>
<file>rc/line_vertical.png</file>
<file>rc/line_vertical@2x.png</file>
<file>rc/line_vertical_disabled.png</file>
<file>rc/line_vertical_disabled@2x.png</file>
<file>rc/line_vertical_focus.png</file>
<file>rc/line_vertical_focus@2x.png</file>
<file>rc/line_vertical_pressed.png</file>
<file>rc/line_vertical_pressed@2x.png</file>
<file>rc/radio_checked.png</file>
<file>rc/radio_checked@2x.png</file>
<file>rc/radio_checked_disabled.png</file>
<file>rc/radio_checked_disabled@2x.png</file>
<file>rc/radio_checked_focus.png</file>
<file>rc/radio_checked_focus@2x.png</file>
<file>rc/radio_checked_pressed.png</file>
<file>rc/radio_checked_pressed@2x.png</file>
<file>rc/radio_unchecked.png</file>
<file>rc/radio_unchecked@2x.png</file>
<file>rc/radio_unchecked_disabled.png</file>
<file>rc/radio_unchecked_disabled@2x.png</file>
<file>rc/radio_unchecked_focus.png</file>
<file>rc/radio_unchecked_focus@2x.png</file>
<file>rc/radio_unchecked_pressed.png</file>
<file>rc/radio_unchecked_pressed@2x.png</file>
<file>rc/toolbar_move_horizontal.png</file>
<file>rc/toolbar_move_horizontal@2x.png</file>
<file>rc/toolbar_move_horizontal_disabled.png</file>
<file>rc/toolbar_move_horizontal_disabled@2x.png</file>
<file>rc/toolbar_move_horizontal_focus.png</file>
<file>rc/toolbar_move_horizontal_focus@2x.png</file>
<file>rc/toolbar_move_horizontal_pressed.png</file>
<file>rc/toolbar_move_horizontal_pressed@2x.png</file>
<file>rc/toolbar_move_vertical.png</file>
<file>rc/toolbar_move_vertical@2x.png</file>
<file>rc/toolbar_move_vertical_disabled.png</file>
<file>rc/toolbar_move_vertical_disabled@2x.png</file>
<file>rc/toolbar_move_vertical_focus.png</file>
<file>rc/toolbar_move_vertical_focus@2x.png</file>
<file>rc/toolbar_move_vertical_pressed.png</file>
<file>rc/toolbar_move_vertical_pressed@2x.png</file>
<file>rc/toolbar_separator_horizontal.png</file>
<file>rc/toolbar_separator_horizontal@2x.png</file>
<file>rc/toolbar_separator_horizontal_disabled.png</file>
<file>rc/toolbar_separator_horizontal_disabled@2x.png</file>
<file>rc/toolbar_separator_horizontal_focus.png</file>
<file>rc/toolbar_separator_horizontal_focus@2x.png</file>
<file>rc/toolbar_separator_horizontal_pressed.png</file>
<file>rc/toolbar_separator_horizontal_pressed@2x.png</file>
<file>rc/toolbar_separator_vertical.png</file>
<file>rc/toolbar_separator_vertical@2x.png</file>
<file>rc/toolbar_separator_vertical_disabled.png</file>
<file>rc/toolbar_separator_vertical_disabled@2x.png</file>
<file>rc/toolbar_separator_vertical_focus.png</file>
<file>rc/toolbar_separator_vertical_focus@2x.png</file>
<file>rc/toolbar_separator_vertical_pressed.png</file>
<file>rc/toolbar_separator_vertical_pressed@2x.png</file>
<file>rc/transparent.png</file>
<file>rc/transparent@2x.png</file>
<file>rc/transparent_disabled.png</file>
<file>rc/transparent_disabled@2x.png</file>
<file>rc/transparent_focus.png</file>
<file>rc/transparent_focus@2x.png</file>
<file>rc/transparent_pressed.png</file>
<file>rc/transparent_pressed@2x.png</file>
<file>rc/window_close.png</file>
<file>rc/window_close@2x.png</file>
<file>rc/window_close_disabled.png</file>
<file>rc/window_close_disabled@2x.png</file>
<file>rc/window_close_focus.png</file>
<file>rc/window_close_focus@2x.png</file>
<file>rc/window_close_pressed.png</file>
<file>rc/window_close_pressed@2x.png</file>
<file>rc/window_grip.png</file>
<file>rc/window_grip@2x.png</file>
<file>rc/window_grip_disabled.png</file>
<file>rc/window_grip_disabled@2x.png</file>
<file>rc/window_grip_focus.png</file>
<file>rc/window_grip_focus@2x.png</file>
<file>rc/window_grip_pressed.png</file>
<file>rc/window_grip_pressed@2x.png</file>
<file>rc/window_minimize.png</file>
<file>rc/window_minimize@2x.png</file>
<file>rc/window_minimize_disabled.png</file>
<file>rc/window_minimize_disabled@2x.png</file>
<file>rc/window_minimize_focus.png</file>
<file>rc/window_minimize_focus@2x.png</file>
<file>rc/window_minimize_pressed.png</file>
<file>rc/window_minimize_pressed@2x.png</file>
<file>rc/window_undock.png</file>
<file>rc/window_undock@2x.png</file>
<file>rc/window_undock_disabled.png</file>
<file>rc/window_undock_disabled@2x.png</file>
<file>rc/window_undock_focus.png</file>
<file>rc/window_undock_focus@2x.png</file>
<file>rc/window_undock_pressed.png</file>
<file>rc/window_undock_pressed@2x.png</file>
</qresource>
<qresource prefix="qdarkstyle/dark">
<file>darkstyle.qss</file>
</qresource>
</RCC>
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 990 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 867 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Some files were not shown because too many files have changed in this diff Show More