Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e2fb18970e | |||
| 184a9ed5f2 | |||
| 0738aff2bf | |||
| d466e5536b | |||
| b9da3e9209 | |||
| ee7aeda91e | |||
| 99bb58adf9 | |||
| 785fde6e2d | |||
| a9b03f081a | |||
| 0634e530b6 | |||
| e6be456cfa | |||
| 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 | |||
| ff3a43a4a6 | |||
| 5a0f0d3e3e | |||
| d60f636881 |
@@ -0,0 +1,88 @@
|
||||
# Change Log
|
||||
|
||||
[中文](doc/CHANGELOG/CHANGELOG_zh_CN.md)
|
||||
|
||||
### V0.2.8
|
||||
+ Add support for Iceman/RRG repo v4.16717
|
||||
+ Fix some bugs
|
||||
+ Make it easier for testing this GUI across multiple clients
|
||||
+ Add support for Bluetooth and TCP connection
|
||||
|
||||
### 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)
|
||||
|
||||
### 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
|
||||
|
||||
### V0.2.2
|
||||
+ Load command format from external json file
|
||||
+ Fix bug [#20](https://github.com/wh201906/Proxmark3GUI/issues/20), [#21](https://github.com/wh201906/Proxmark3GUI/issues/21), [#22](https://github.com/wh201906/Proxmark3GUI/issues/22)
|
||||
+ Support Iceman/RRG repo v4.13441
|
||||
|
||||
### V0.2.1
|
||||
+ Optimize MIFARE Classic reading logic
|
||||
+ Fix bug [#16](https://github.com/wh201906/Proxmark3GUI/issues/16)
|
||||
+ Fix bug [#15](https://github.com/wh201906/Proxmark3GUI/issues/15) partially (the path can contain spaces now)
|
||||
|
||||
### V0.2
|
||||
+ Use Dock widget for more flexible layout
|
||||
+ Support basic LF commands
|
||||
+ Fix a bug in RawCommand tab
|
||||
|
||||
### V0.1.4
|
||||
+ Optimize performance
|
||||
+ Optimize UI
|
||||
+ Search available ports automatically
|
||||
+ Add High-DPI support
|
||||
+ Support configuring environment variables by script
|
||||
(Useful when the client requires specific environment variables)
|
||||
+ All functions are compatible with Iceman/RRG repo(tested on v4.9237)
|
||||
+ Support specifying client working directory
|
||||
+ Fix some bugs
|
||||
|
||||
### V0.1.3
|
||||
+ Fix Trailer Decoder
|
||||
+ Add feedback when writing selected blocks
|
||||
|
||||
### V0.1.2
|
||||
+ Optimize read logic
|
||||
+ Make UI Customizable
|
||||
+ Save client path automatically
|
||||
+ Add Trailer Decoder(Deprecated, plz use V0.1.3 or higher version)
|
||||
+ Support read/write selected blocks
|
||||
+ Support a few Iceman functions
|
||||
+ Fix some bugs
|
||||
|
||||
### V0.1.1
|
||||
+ Complete Mifare module(support simulate and sniff)
|
||||
|
||||
### V0.1
|
||||
+ Able to deal with Mifare card and related files
|
||||
|
||||
### V0.0.1
|
||||
+ a dumb version with a useless GUI and a serial choose box.
|
||||
@@ -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,79 +44,55 @@ 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
|
||||
|
||||
[1.Quickstart](doc/tutorial/Quickstart/quickstart.md)
|
||||
[2.Edit Mifare Classic data](doc/tutorial/Edit_Mifare_Classic_data/Edit_Mifare_Classic_data.md)(Proxmark3 hardware is not necessary)
|
||||
[2.Work with ProxSpace](doc/tutorial/Work_With_ProxSpace/work_with_proxspace.md)
|
||||
[3.Edit Mifare Classic data](doc/tutorial/Edit_Mifare_Classic_data/Edit_Mifare_Classic_data.md)(Proxmark3 hardware is not necessary)
|
||||
|
||||
***
|
||||
|
||||
## Update Log:
|
||||
|
||||
### 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
|
||||
|
||||
### V0.2.2
|
||||
+ Load command format from external json file
|
||||
+ Fix bug [#20](https://github.com/wh201906/Proxmark3GUI/issues/20), [#21](https://github.com/wh201906/Proxmark3GUI/issues/21), [#22](https://github.com/wh201906/Proxmark3GUI/issues/22)
|
||||
+ Support Iceman/RRG repo v4.13441
|
||||
|
||||
### V0.2.1
|
||||
+ Optimize MIFARE Classic reading logic
|
||||
+ Fix bug [#16](https://github.com/wh201906/Proxmark3GUI/issues/16)
|
||||
+ Fix bug [#15](https://github.com/wh201906/Proxmark3GUI/issues/15) partially (the path can contain spaces now)
|
||||
|
||||
### V0.2
|
||||
+ Use Dock widget for more flexible layout
|
||||
+ Support basic LF commands
|
||||
+ Fix a bug in RawCommand tab
|
||||
|
||||
### V0.1.4
|
||||
+ Optimize performance
|
||||
+ Optimize UI
|
||||
+ Search available ports automatically
|
||||
+ Add High-DPI support
|
||||
+ Support configuring environment variables by script
|
||||
(Useful when the client requires specific environment variables)
|
||||
+ All functions are compatible with Iceman/RRG repo(tested on v4.9237)
|
||||
+ Support specifying client working directory
|
||||
+ Fix some bugs
|
||||
|
||||
### V0.1.3
|
||||
+ Fix Trailer Decoder
|
||||
+ Add feedback when writing selected blocks
|
||||
|
||||
### V0.1.2
|
||||
+ Optimize read logic
|
||||
+ Make UI Customizable
|
||||
+ Save client path automatically
|
||||
+ Add Trailer Decoder(Deprecated, plz use V0.1.3 or higher version)
|
||||
+ Support read/write selected blocks
|
||||
+ Support a few Iceman functions
|
||||
+ Fix some bugs
|
||||
|
||||
### V0.1.1
|
||||
+ Complete Mifare module(support simulate and sniff)
|
||||
|
||||
### V0.1
|
||||
+ Able to deal with Mifare card and related files
|
||||
|
||||
### V0.0.1
|
||||
+ a dumb version with a useless GUI and a serial choose box.
|
||||
## Change Log
|
||||
[Change Log](CHANGELOG.md)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<RCC>
|
||||
<qresource prefix="/config">
|
||||
<file>config_official.json</file>
|
||||
<file>config_rrgv4.13441.json</file>
|
||||
<file>config_rrgv4.15864.json</file>
|
||||
<file>config_rrgv4.16717.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"//": "Based on Proxmark3 official repo v3.1.0, commit 6116334",
|
||||
"//": "Based on Proxmark3 official repo v3.1.0, commit 6116334485",
|
||||
"//": "You can change this file if the command format of client changes",
|
||||
"mifare classic": {
|
||||
"nested": {
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"//": "Based on Proxmark3 rrg repo v4.13441, commit 35ddebc",
|
||||
"//": "Based on Proxmark3 rrg repo v4.13441, commit 35ddebc03c",
|
||||
"//": "You can change this file if the command format of client changes",
|
||||
"mifare classic": {
|
||||
"nested": {
|
||||
@@ -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,12 +34,22 @@
|
||||
"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
|
||||
},
|
||||
"info": {
|
||||
"cmd": "hf 14a info"
|
||||
"cmd": "hf 14a info -nsv",
|
||||
"basic cmd": "hf 14a info"
|
||||
},
|
||||
"sniff": {
|
||||
"cmd": "hf sniff"
|
||||
@@ -44,10 +61,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 +229,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,242 @@
|
||||
{
|
||||
"//": "Based on Proxmark3 rrg repo v4.15864, commit 1f75adcf6d",
|
||||
"//": "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 -nsv",
|
||||
"basic 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": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
{
|
||||
"//": "Based on Proxmark3 rrg repo v4.16717, commit adfebd6510",
|
||||
"//": "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 -nsv",
|
||||
"basic 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> --force",
|
||||
"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>",
|
||||
"path cmd":"prefs show",
|
||||
"path pattern":"trace save path\\.+\\s*(.+)$"
|
||||
},
|
||||
"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": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/V*-*
|
||||
/V*-*/
|
||||
/32/
|
||||
/64/
|
||||
/client/
|
||||
@@ -0,0 +1,3 @@
|
||||
# Deploy helper
|
||||
Just for generating Github release
|
||||
Useless for general users
|
||||
@@ -0,0 +1,151 @@
|
||||
import os, sys, shutil
|
||||
from win32api import GetFileVersionInfo
|
||||
from json import load
|
||||
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,
|
||||
)
|
||||
except Exception:
|
||||
print("Cannot get version number of", fname)
|
||||
return version
|
||||
|
||||
|
||||
os.chdir(sys.path[0])
|
||||
print("Current Directory:", os.getcwd())
|
||||
targetName = os.path.abspath(os.getcwd()).split("\\")[-2]
|
||||
print("Target Name", targetName)
|
||||
|
||||
src32Dir = ""
|
||||
src64Dir = ""
|
||||
dirList = os.listdir("../")
|
||||
|
||||
for i in dirList:
|
||||
if not os.path.isdir("../" + i):
|
||||
continue
|
||||
if not i.startswith("build"):
|
||||
continue
|
||||
|
||||
if i.endswith("32_bit-Release"):
|
||||
src32Dir = "../" + i
|
||||
elif i.endswith("64_bit-Release"):
|
||||
src64Dir = "../" + i
|
||||
|
||||
src32Path = src32Dir + "/release/" + targetName + ".exe"
|
||||
src64Path = src64Dir + "/release/" + targetName + ".exe"
|
||||
print("Target Files:")
|
||||
print(src32Path)
|
||||
print(src64Path)
|
||||
|
||||
ver32 = getPEVersion(src32Path)
|
||||
ver64 = getPEVersion(src64Path)
|
||||
print("Versions:")
|
||||
print("win32:", ver32)
|
||||
print("win64:", ver64)
|
||||
if ver32 != ver64:
|
||||
print("WARNING!")
|
||||
print("Version names are not the same!")
|
||||
dst32Dir = "./" + ver32 + "-win32"
|
||||
dst64Dir = "./" + ver64 + "-win64"
|
||||
dst32Path = dst32Dir + "/" + targetName + ".exe"
|
||||
dst64Path = dst64Dir + "/" + targetName + ".exe"
|
||||
|
||||
if os.path.exists(dst32Dir) and os.path.exists(dst32Path):
|
||||
print(dst32Path, "exists, replacing...")
|
||||
os.remove(dst32Path)
|
||||
elif not os.path.exists(dst32Dir):
|
||||
print(dst32Dir, "doesn't exist, creating...")
|
||||
shutil.copytree("./32", dst32Dir)
|
||||
shutil.copyfile(src32Path, dst32Path)
|
||||
compressDirList.append(dst32Dir)
|
||||
|
||||
if os.path.exists(dst64Dir) and os.path.exists(dst64Path):
|
||||
print(dst64Path, "exists, replacing...")
|
||||
os.remove(dst64Path)
|
||||
elif not os.path.exists(dst64Dir):
|
||||
print(dst64Dir, "doesn't exist, creating...")
|
||||
shutil.copytree("./64", dst64Dir)
|
||||
shutil.copyfile(src64Path, dst64Path)
|
||||
compressDirList.append(dst64Dir)
|
||||
|
||||
# TODO: GUI+client
|
||||
clientList = [
|
||||
"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
|
||||
clientSrcDir = "./client/" + clientName
|
||||
clientDstDir = "./" + ver64 + "-win64-" + clientName
|
||||
clientDstGUIDir = clientDstDir + "/GUI"
|
||||
|
||||
if os.path.exists(clientDstDir) and os.path.exists(clientDstGUIDir):
|
||||
print(clientDstGUIDir, "exists, replacing...")
|
||||
shutil.rmtree(clientDstGUIDir)
|
||||
elif not os.path.exists(clientDstDir):
|
||||
print(clientDstDir, "doesn't exist, creating...")
|
||||
shutil.copytree(clientSrcDir, clientDstDir)
|
||||
shutil.copytree(dst64Dir, clientDstGUIDir)
|
||||
if "official" in clientName:
|
||||
shutil.copyfile(
|
||||
"./client/GUIsettings_Official.ini", clientDstGUIDir + "/GUIsettings.ini"
|
||||
)
|
||||
elif "rrg" in clientName:
|
||||
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:
|
||||
generateClient(cl)
|
||||
|
||||
use7z = input("Compress?(y/N)")
|
||||
if fullmatch("yes|y", use7z, IGNORECASE):
|
||||
print(compressDirList)
|
||||
for it in compressDirList:
|
||||
archivePath = it + ".7z"
|
||||
|
||||
if os.path.exists(archivePath):
|
||||
print(archivePath, "exists, replacing...")
|
||||
os.remove(archivePath)
|
||||
os.system("7z a -t7z -mmt8 -mx9 " + archivePath + " " + it)
|
||||
@@ -0,0 +1,88 @@
|
||||
# 更新日志
|
||||
|
||||
[English](../../CHANGELOG.md)
|
||||
|
||||
### V0.2.8
|
||||
+ 支持冰人版客户端 v4.16717
|
||||
+ 修复若干Bug
|
||||
+ 便于在不同版本客户端之间切换
|
||||
+ 支持蓝牙及TCP连接
|
||||
|
||||
### 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)
|
||||
|
||||
### V0.2.4
|
||||
+ 复制EM410x卡(一种常见的低频ID卡)
|
||||
|
||||
### V0.2.3
|
||||
+ 修复 [#27](https://github.com/wh201906/Proxmark3GUI/issues/27)
|
||||
+ 尝试支持中文启动路径
|
||||
|
||||
### V0.2.2
|
||||
+ 从外部文件加载客户端命令格式
|
||||
+ 修复 [#20](https://github.com/wh201906/Proxmark3GUI/issues/20), [#21](https://github.com/wh201906/Proxmark3GUI/issues/21), [#22](https://github.com/wh201906/Proxmark3GUI/issues/22)
|
||||
+ 兼容冰人版客户端 v4.13441
|
||||
|
||||
### V0.2.1
|
||||
+ 优化MIFARE Classic读卡逻辑
|
||||
+ 修复 [#16](https://github.com/wh201906/Proxmark3GUI/issues/16) (配合新版RRG固件时无法读取扇区数据)
|
||||
+ 修复 [#15](https://github.com/wh201906/Proxmark3GUI/issues/15) (路径中支持空格)
|
||||
|
||||
### V0.2
|
||||
+ 使用浮动窗口,界面配置更加灵活
|
||||
+ 支持部分低频命令
|
||||
+ 修复原始命令选项卡中的一个Bug
|
||||
|
||||
### V0.1.4
|
||||
+ 优化性能
|
||||
+ 优化用户界面
|
||||
+ 自动搜索可用端口
|
||||
+ 支持高分屏
|
||||
+ 可通过外部脚本配置环境变量
|
||||
(在客户端需要配置环境变量时很有用)
|
||||
+ 全功能兼容冰人版(在v4.9237上测试通过)
|
||||
+ 支持指定客户端工作路径
|
||||
+ 修复部分bug
|
||||
|
||||
### V0.1.3
|
||||
+ 修复访问控制位解码器
|
||||
+ 写多个块时显示写入结果
|
||||
|
||||
### V0.1.2
|
||||
+ 优化读卡逻辑
|
||||
+ UI自定义
|
||||
+ 自动保存客户端路径
|
||||
+ 添加访问控制位解码器(也可用于自己构造访问控制位)(有bug,请使用V0.1.3或更高版本)
|
||||
+ 支持仅读写选中块
|
||||
+ 支持部分冰人功能
|
||||
+ 修复部分bug
|
||||
|
||||
### V0.1.1
|
||||
+ 完成整个Mifare模块(支持模拟卡和嗅探功能)
|
||||
|
||||
### V0.1
|
||||
+ 支持处理Mifare卡片及相关数据文件
|
||||
|
||||
### V0.0.1
|
||||
+ 一个带串口选择框的实验版本
|
||||
@@ -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,77 +44,52 @@ 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下正确连接设备,需要更改一些设置
|
||||
|
||||

|
||||
|
||||
***
|
||||
## 教程
|
||||
[1.快速上手](../tutorial/Quickstart/quickstart_zh_CN.md)
|
||||
[2.编辑Mifare(IC)卡数据](../tutorial/Edit_Mifare_Classic_data/Edit_Mifare_Classic_data_zh_CN.md)(无需PM3硬件)
|
||||
[2.使用ProxSpace编译的客户端](../tutorial/Work_With_ProxSpace/work_with_proxspace_zh_CN.md)
|
||||
[3.编辑Mifare(IC)卡数据](../tutorial/Edit_Mifare_Classic_data/Edit_Mifare_Classic_data_zh_CN.md)(无需PM3硬件)
|
||||
***
|
||||
## 更新日志:
|
||||
|
||||
### V0.2.4
|
||||
+ 复制EM410x卡(一种常见的低频ID卡)
|
||||
|
||||
### V0.2.3
|
||||
+ 修复 [#27](https://github.com/wh201906/Proxmark3GUI/issues/27)
|
||||
+ 尝试支持中文启动路径
|
||||
|
||||
### V0.2.2
|
||||
+ 从外部文件加载客户端命令格式
|
||||
+ 修复 [#20](https://github.com/wh201906/Proxmark3GUI/issues/20), [#21](https://github.com/wh201906/Proxmark3GUI/issues/21), [#22](https://github.com/wh201906/Proxmark3GUI/issues/22)
|
||||
+ 兼容冰人版客户端 v4.13441
|
||||
|
||||
### V0.2.1
|
||||
+ 优化MIFARE Classic读卡逻辑
|
||||
+ 修复 [#16](https://github.com/wh201906/Proxmark3GUI/issues/16) (配合新版RRG固件时无法读取扇区数据)
|
||||
+ 修复 [#15](https://github.com/wh201906/Proxmark3GUI/issues/15) (路径中支持空格)
|
||||
|
||||
### V0.2
|
||||
+ 使用浮动窗口,界面配置更加灵活
|
||||
+ 支持部分低频命令
|
||||
+ 修复原始命令选项卡中的一个Bug
|
||||
|
||||
### V0.1.4
|
||||
+ 优化性能
|
||||
+ 优化用户界面
|
||||
+ 自动搜索可用端口
|
||||
+ 支持高分屏
|
||||
+ 可通过外部脚本配置环境变量
|
||||
(在客户端需要配置环境变量时很有用)
|
||||
+ 全功能兼容冰人版(在v4.9237上测试通过)
|
||||
+ 支持指定客户端工作路径
|
||||
+ 修复部分bug
|
||||
|
||||
### V0.1.3
|
||||
+ 修复访问控制位解码器
|
||||
+ 写多个块时显示写入结果
|
||||
|
||||
### V0.1.2
|
||||
+ 优化读卡逻辑
|
||||
+ UI自定义
|
||||
+ 自动保存客户端路径
|
||||
+ 添加访问控制位解码器(也可用于自己构造访问控制位)(有bug,请使用V0.1.3或更高版本)
|
||||
+ 支持仅读写选中块
|
||||
+ 支持部分冰人功能
|
||||
+ 修复部分bug
|
||||
|
||||
### V0.1.1
|
||||
+ 完成整个Mifare模块(支持模拟卡和嗅探功能)
|
||||
|
||||
### V0.1
|
||||
+ 支持处理Mifare卡片及相关数据文件
|
||||
|
||||
### V0.0.1
|
||||
+ 一个带串口选择框的实验版本
|
||||
## 更新日志
|
||||
[更新日志](../CHANGELOG/CHANGELOG_zh_CN.md)
|
||||
|
||||
|
After Width: | Height: | Size: 115 KiB |
@@ -27,10 +27,10 @@
|
||||
(4) Go to "Settings" panel. Input the config file path which matching the client you use.
|
||||

|
||||
|
||||
(5) If setup.bat is required, input the script path in the "Preload script path" editbox.
|
||||
(5) If setup.bat is required, input the script path in the "Preload script path" editbox.
|
||||

|
||||
|
||||
(6) If using RRG/Iceman repo, input "-p \<port\> -f" in the "Start arguments" editbox.
|
||||
(6) If using RRG/Iceman repo, input "-p \<port\> -f" in the "Start arguments" editbox.
|
||||

|
||||
|
||||
***
|
||||
@@ -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
|
||||
```
|
||||
如果需要使用其它客户端,你可以参考此文件编写自己的脚本,然后将其填入“预加载脚本路径”当中
|
||||
@@ -0,0 +1,81 @@
|
||||
# Work with ProxSpace
|
||||
|
||||
[中文教程](work_with_proxspace_zh_CN.md)
|
||||
This GUI supports clients built from ProxSpace, making it easier to use the latest client with this GUI.
|
||||
|
||||
## 1. Set up ProxSpace
|
||||
Please refer to this tutorial to set up ProxSpace and compile Proxmark3 client:
|
||||
https://github.com/Gator96100/ProxSpace/blob/HEAD/README.md
|
||||
|
||||
After that, you will get a folder structure like this:
|
||||
```
|
||||
.
|
||||
├── autobuild.bat
|
||||
├── msys2
|
||||
│ ├── autorebase.bat
|
||||
│ └── ......
|
||||
├── pm3
|
||||
│ └── proxmark3
|
||||
│ ├── client
|
||||
│ ├── ......
|
||||
│ ├── pm3
|
||||
│ ├── README.md
|
||||
│ └── ......
|
||||
├── README.md
|
||||
├── runme64.bat
|
||||
└── setup
|
||||
└── ......
|
||||
```
|
||||
The proxmark3 repository is located in `./pm3/proxmark3`
|
||||
|
||||
## 2. Download GUI
|
||||
You can download prebuilt binaries there.
|
||||
[Prebuilt binaries](../../../README.md#download-binaries-for-windows)
|
||||
Please download a version without the client, like `V0.2.7-win64.7z`.
|
||||
After downloading, extract it to a path without non-ASCII characters and spaces. Plus, the target folder should not be the same as the proxmark3 repository.
|
||||
For example, if you extract it to ./pm3/GUI/, you will get a folder structure like this:
|
||||
```
|
||||
.
|
||||
├── autobuild.bat
|
||||
├── msys2
|
||||
│ ├── autorebase.bat
|
||||
│ └── ......
|
||||
├── pm3
|
||||
│ ├── GUI
|
||||
│ │ └── V0.2.7-win64
|
||||
│ │ ├── plugins
|
||||
│ │ ├── Proxmark3GUI.exe
|
||||
│ │ └── ......
|
||||
│ └── proxmark3
|
||||
│ ├── client
|
||||
│ ├── ......
|
||||
│ ├── pm3
|
||||
│ ├── README.md
|
||||
│ └── ......
|
||||
├── README.md
|
||||
├── runme64.bat
|
||||
└── setup
|
||||
└── ......
|
||||
```
|
||||
|
||||
## 3. Run the GUI in ProxSpace
|
||||
Double-click `./runme64.bat` to run the ProxSpace. Now the working directory is `./pm3`.
|
||||
In the terminal of ProxSpace, run `cd GUI` to go to the `./pm3/GUI`, then run `./V0.2.7-win64/Proxmark3GUI.exe` to open the GUI.
|
||||
***
|
||||
**Note:** You can run the GUI in your preferred folder, but please avoid running it in the same directory as the GUI itself, otherwise it will cause errors when loading the client.
|
||||
Using the directory structure above as an example, you can first run `cd /pm3` to set the working directory to `/pm3`, then run `./V0.2.7-win64/Proxmark3GUI.exe` to open the GUI.
|
||||
However, you should not first run `cd /pm3/GUI/V0.2.7-win64` and then run `./Proxmark3GUI.exe`.
|
||||
|
||||
## 4. Connect to the device in GUI
|
||||
|
||||
## Specify the Client Path
|
||||
Using the directory structure above as an example, assuming the current working directory is `./pm3/GUI`, and the client path is `./pm3/proxmark3/client/proxmark3.exe`, you need to enter `../proxmark3/client/proxmark3.exe` in the `Client Path`.
|
||||
|
||||
## Clear the Preload Script Path
|
||||
The GUI is launched in ProxSpace so it includes the necessary environment variables for the client, there is no need to use any preload script.
|
||||
|
||||
## Select the Config File
|
||||
Depending on the client version, you need to select the corresponding config file. For example, select `config_official.json` for the official client, and select `config_rrgv4.15864.json` for the rrg version v4.15864. If your client version is not listed, try selecting the config file with a similar version number.
|
||||
|
||||
## Connect to the Device
|
||||
Select the port number of the PM3 hardware, then click `Connect`.
|
||||
@@ -0,0 +1,77 @@
|
||||
# 使用ProxSpace编译的客户端
|
||||
|
||||
[English](work_with_proxspace.md)
|
||||
此GUI可以和ProxSpace编译出来的客户端配合运行,满足一部分用户使用最新版客户端的需求
|
||||
|
||||
## 1. 搭建ProxSpace环境
|
||||
请参考此教程搭建ProxSpace环境并编译proxmark3客户端:
|
||||
https://github.com/Gator96100/ProxSpace/blob/HEAD/README.md
|
||||
|
||||
搭建完成后,你将会获得如下的目录结构:
|
||||
```
|
||||
.
|
||||
├── autobuild.bat
|
||||
├── msys2
|
||||
│ ├── autorebase.bat
|
||||
│ └── ......
|
||||
├── pm3
|
||||
│ └── proxmark3
|
||||
│ ├── client
|
||||
│ ├── ......
|
||||
│ ├── pm3
|
||||
│ ├── README.md
|
||||
│ └── ......
|
||||
├── README.md
|
||||
├── runme64.bat
|
||||
└── setup
|
||||
└── ......
|
||||
```
|
||||
其中proxmark3仓库位于 `./pm3/proxmark3`
|
||||
|
||||
## 2. 下载GUI
|
||||
你可以在此处下载编译好的客户端
|
||||
[预编译客户端](../../README/README_zh_CN.md#关于预编译windows客户端)
|
||||
下载时请选择不含客户端的版本,例如`V0.2.7-win64.7z`
|
||||
下载后请将其解压到不含中文字符和空格的路径中,同时要确保GUI文件和proxmark3仓库不位于同一文件夹下
|
||||
以解压到`./pm3/GUI/`为例,你将会获得如下的目录结构
|
||||
```
|
||||
.
|
||||
├── autobuild.bat
|
||||
├── msys2
|
||||
│ ├── autorebase.bat
|
||||
│ └── ......
|
||||
├── pm3
|
||||
│ ├── GUI
|
||||
│ │ └── V0.2.7-win64
|
||||
│ │ ├── plugins
|
||||
│ │ ├── Proxmark3GUI.exe
|
||||
│ │ └── ......
|
||||
│ └── proxmark3
|
||||
│ ├── client
|
||||
│ ├── ......
|
||||
│ ├── pm3
|
||||
│ ├── README.md
|
||||
│ └── ......
|
||||
├── README.md
|
||||
├── runme64.bat
|
||||
└── setup
|
||||
└── ......
|
||||
```
|
||||
|
||||
## 3. 从ProxSpace运行GUI
|
||||
双击`./runme64.bat`运行ProxSpace环境,此时工作目录位于`./pm3`
|
||||
在新弹出的终端中运行`cd GUI`来到`./pm3/GUI/`目录下,然后运行`./V0.2.7-win64/Proxmark3GUI.exe`,此时的GUI将会包含客户端运行所需要的所有环境变量
|
||||
***
|
||||
**请注意**,你可以在你喜欢的工作目录下运行GUI,但请不要在GUI文件所在目录下运行,否则加载客户端时会出错
|
||||
以上面的目录结构为例,你可以先运行`cd /pm3`将工作目录设为`/pm3`,然后运行`./V0.2.7-win64/Proxmark3GUI.exe`来打开GUI
|
||||
但是你不能先运行`cd /pm3/GUI/V0.2.7-win64`,然后运行`./Proxmark3GUI.exe`,否则之后无法正确加载客户端
|
||||
|
||||
## 4. 从GUI连接设备
|
||||
### 填写客户端路径
|
||||
以上面的目录结构为例,假设此时的工作目录为`./pm3/GUI`,而客户端路径为`./pm3/proxmark3/client/proxmark3.exe`,则需要在客户端路径里面填写`../proxmark3/client/proxmark3.exe`
|
||||
### 清空预加载脚本路径
|
||||
因为GUI是从ProxSpace中启动的,本身已包含客户端所需的环境变量,因此不需要使用任何预加载脚本
|
||||
### 选择(客户端)配置文件
|
||||
根据客户端版本的不同,你需要选择对应的配置文件。例如official版本对应`config_official.json`,rrg版本号v4.15864对应`config_rrgv4.15864.json`。如果选项中没有你所使用的客户端版本,可以尝试选择版本号相近的对应配置文件
|
||||
### 连接设备
|
||||
在“端口”当中选择需要连接的端口号,单击“连接”即可
|
||||
@@ -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.4
|
||||
VERSION = 0.2.8
|
||||
QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
|
||||
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
|
||||
QMAKE_TARGET_DESCRIPTION = "A cross-platform GUI for Proxmark3 client"
|
||||
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,13 +28,14 @@ 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);
|
||||
setRequiringOutput(false);
|
||||
result = *requiredOutput;
|
||||
if(result.indexOf("[=]") != -1)
|
||||
if(result.contains("[=]"))
|
||||
{
|
||||
clientType = Util::CLIENTTYPE_ICEMAN;
|
||||
setRequiringOutput(true);
|
||||
@@ -41,7 +44,7 @@ void PM3Process::connectPM3(const QString& path, const QStringList args)
|
||||
{
|
||||
waitForReadyRead(200);
|
||||
result += *requiredOutput;
|
||||
if(result.indexOf("os: ") != -1)
|
||||
if(result.contains("os: "))
|
||||
break;
|
||||
}
|
||||
setRequiringOutput(false);
|
||||
@@ -50,7 +53,7 @@ void PM3Process::connectPM3(const QString& path, const QStringList args)
|
||||
{
|
||||
clientType = Util::CLIENTTYPE_OFFICIAL;
|
||||
}
|
||||
if(result.indexOf("os: ") != -1) // make sure the PM3 is connected
|
||||
if(result.contains("os: ")) // make sure the PM3 is connected
|
||||
{
|
||||
emit changeClientType(clientType);
|
||||
result = result.mid(result.indexOf("os: "));
|
||||
@@ -59,8 +62,14 @@ void PM3Process::connectPM3(const QString& path, const QStringList args)
|
||||
emit PM3StatedChanged(true, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "unexpected output:" << (result.isEmpty() ? "(empty)" : result);
|
||||
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);
|
||||
@@ -149,6 +151,7 @@ void LF::syncWithUI()
|
||||
ui->LF_LFConf_averagingBox->setChecked(currLFConfig.averaging);
|
||||
ui->LF_LFConf_thresholdBox->setValue(currLFConfig.triggerThreshold);
|
||||
ui->LF_LFConf_skipsBox->setValue(currLFConfig.samplesToSkip);
|
||||
emit LFfreqConfChanged(currLFConfig.divisor, false);
|
||||
}
|
||||
|
||||
void LF::setConfigMap(const QVariantMap& configMap)
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
void syncWithUI();
|
||||
bool getLFConfig_helper(const QVariantMap& map, QString& str, int* result);
|
||||
signals:
|
||||
|
||||
void LFfreqConfChanged(int divisor, bool isCustomized);
|
||||
};
|
||||
|
||||
#endif // LF_H
|
||||
|
||||
@@ -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)
|
||||
@@ -99,17 +102,22 @@ QMap<QString, QString> Mifare::info(bool isRequiringOutput)
|
||||
QVariantMap config = configMap["info"].toMap();
|
||||
if(isRequiringOutput)
|
||||
{
|
||||
QString result = util->execCMDWithOutput(config["cmd"].toString(), 500);
|
||||
QString cmd = config["basic cmd"].toString();
|
||||
|
||||
// for official client
|
||||
if(cmd.isEmpty())
|
||||
cmd = config["cmd"].toString();
|
||||
QString result = util->execCMDWithOutput(cmd, 500);
|
||||
QStringList lineList = result.split("\n");
|
||||
|
||||
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 +138,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 +177,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 +220,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 +647,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 +699,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 +718,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 +755,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 +1320,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 +1342,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;
|
||||
@@ -1350,3 +1375,18 @@ quint16 Mifare::getTrailerBlockId(quint8 sectorId, qint8 cardTypeId)
|
||||
// other cardTypeId: use current cardtype(include default -1)
|
||||
return (cardType.blks[sectorId] + cardType.blk[sectorId] - 1);
|
||||
}
|
||||
|
||||
QString Mifare::getTraceSavePath()
|
||||
{
|
||||
QVariantMap config = configMap["save sniff"].toMap();
|
||||
QString pathCmd = config["path cmd"].toString();
|
||||
QString patternText = config["path pattern"].toString();
|
||||
QRegularExpression pattern = QRegularExpression(patternText, QRegularExpression::MultilineOption);
|
||||
if(pathCmd.isEmpty() || patternText.isEmpty())
|
||||
return QString();
|
||||
QString result = util->execCMDWithOutput(pathCmd, 500);
|
||||
QRegularExpressionMatch reMatch = pattern.match(result);
|
||||
if(!reMatch.hasMatch())
|
||||
return QString();
|
||||
return reMatch.captured(1).trimmed();
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ public:
|
||||
QString data_getUID();
|
||||
quint16 getTrailerBlockId(quint8 sectorId, qint8 cardTypeId = -1); // -1: use current cardtype
|
||||
void setConfigMap(const QVariantMap& configMap);
|
||||
QString getTraceSavePath();
|
||||
public slots:
|
||||
signals:
|
||||
|
||||
|
||||
@@ -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 |