Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aee621c196 | |||
| b788d6a15f | |||
| 92d704bc96 | |||
| d671266797 | |||
| 5a26cd1936 | |||
| 5b84e58ecb | |||
| 29bac475b5 | |||
| 6926b2f170 | |||
| aaf6e52a12 | |||
| b3001e71b7 | |||
| a7e112f124 | |||
| c2d3248b68 | |||
| 2723abd260 | |||
| 9aff432b1b | |||
| ce973fda96 | |||
| 2704b7cfc2 | |||
| 2b5c94974d | |||
| d8d9178ce8 | |||
| 9c89df4519 | |||
| 757fdcfc21 | |||
| a9b19f92d6 | |||
| b2cb1ea8e7 | |||
| da2f6ead6e | |||
| 3c6d5e4d82 | |||
| 8105aba254 | |||
| ebf1980af5 | |||
| fd0f9c081f | |||
| ef9972d24a | |||
| 8739dde6a2 | |||
| 2e1e8a0ae5 | |||
| 9b206d6828 | |||
| 3b1092304c | |||
| 924178dffa | |||
| 953e686785 | |||
| a2d63b5cdc | |||
| 9dcd291894 |
@@ -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
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
# Proxmark3GUI
|
||||

|
||||
[](https://github.com/wh201906/Proxmark3GUI/releases)
|
||||
[](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
|
||||
[](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
|
||||
|
||||

|
||||
|
||||
***
|
||||
## Tutorial
|
||||
|
||||
@@ -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>
|
||||
@@ -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": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
# Proxmark3GUI
|
||||

|
||||
[](https://github.com/wh201906/Proxmark3GUI/releases)
|
||||
[](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/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平台上也可下载
|
||||
[](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下正确连接设备,需要更改一些设置
|
||||
|
||||

|
||||
|
||||
***
|
||||
## 教程
|
||||
|
||||
|
After Width: | Height: | Size: 115 KiB |
@@ -41,5 +41,26 @@
|
||||
(3) You might need to change "\<port\>" to "/dev/\<port\>" in "Settings"->"Start arguments" editbox
|
||||

|
||||
|
||||
(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
|
||||

|
||||
(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
|
||||

|
||||
|
||||
## 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.
|
||||
@@ -46,4 +46,26 @@
|
||||

|
||||
|
||||
(4) 若使用树莓派Raspbian系统且连接成功若干秒后PM3会自动断开,则需要在“设置”面板中勾选“在PM3断开后保持客户端运行”
|
||||

|
||||

|
||||
|
||||
## 预加载脚本
|
||||
客户端在运行时可能需要使用某些环境变量以解决依赖问题
|
||||
例如,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
|
||||
```
|
||||
如果需要使用其它客户端,你可以参考此文件编写自己的脚本,然后将其填入“预加载脚本路径”当中
|
||||
@@ -1,4 +1,3 @@
|
||||
[Languages]
|
||||
en_US=English
|
||||
zh_CN=简体中文
|
||||
ext=Load from external 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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
From commit 6ff5fdf of [QDarkStyleSheet](https://github.com/ColinDuquesnoy/QDarkStyleSheet)
|
||||
@@ -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>
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
After Width: | Height: | Size: 522 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 546 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 523 B |
|
After Width: | Height: | Size: 992 B |
|
After Width: | Height: | Size: 567 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 558 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 557 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 551 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 574 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 546 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 545 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 541 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 574 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 525 B |
|
After Width: | Height: | Size: 1008 B |
|
After Width: | Height: | Size: 549 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 532 B |
|
After Width: | Height: | Size: 990 B |
|
After Width: | Height: | Size: 554 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 397 B |
|
After Width: | Height: | Size: 824 B |
|
After Width: | Height: | Size: 426 B |
|
After Width: | Height: | Size: 862 B |
|
After Width: | Height: | Size: 395 B |
|
After Width: | Height: | Size: 810 B |
|
After Width: | Height: | Size: 415 B |
|
After Width: | Height: | Size: 867 B |
|
After Width: | Height: | Size: 151 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 152 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 149 B |
|
After Width: | Height: | Size: 203 B |
|
After Width: | Height: | Size: 152 B |
|
After Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 133 B |
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 135 B |
|
After Width: | Height: | Size: 240 B |
|
After Width: | Height: | Size: 134 B |
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 135 B |
|
After Width: | Height: | Size: 239 B |
|
After Width: | Height: | Size: 166 B |
|
After Width: | Height: | Size: 260 B |
|
After Width: | Height: | Size: 167 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 164 B |