mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-22 22:33:48 -07:00
Merge branch 'master' into master
Signed-off-by: Óscar Alfonso Díaz <oscar.alfonso.diaz@gmail.com>
This commit is contained in:
commit
6a8bb34eac
6 changed files with 162 additions and 35 deletions
|
@ -4,6 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
- Added python3 script to convert amiibo nfc Flipper Zero files to eml files to be used with Proxmark3 (@OscarAkaElvis)
|
- Added python3 script to convert amiibo nfc Flipper Zero files to eml files to be used with Proxmark3 (@OscarAkaElvis)
|
||||||
|
- Changed `hf mf restore` - Auth both key A and key B with default password (@wh201906)
|
||||||
- Changed `nfc decode -f` - now can detect and convert MFC dumpfiles to NDEF byte arrays (@iceman1001)
|
- Changed `nfc decode -f` - now can detect and convert MFC dumpfiles to NDEF byte arrays (@iceman1001)
|
||||||
- Changed `nfc decode` - now handles EXTERNAL RECORDS better (@iceman1001)
|
- Changed `nfc decode` - now handles EXTERNAL RECORDS better (@iceman1001)
|
||||||
- Fixed `nfc decode` - now handles NDEF Signature version1 records better (@iceman1001)
|
- Fixed `nfc decode` - now handles NDEF Signature version1 records better (@iceman1001)
|
||||||
|
@ -62,6 +63,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Update documentation for installation on macOS with MacPorts (@linuxgemini)
|
- Update documentation for installation on macOS with MacPorts (@linuxgemini)
|
||||||
- Added possible Paxton id to hitag2 tag info output
|
- Added possible Paxton id to hitag2 tag info output
|
||||||
- Changed `hf mf sim` - reduce 50ms threshold to 6ms for reset to idle #1974 (@net147)
|
- Changed `hf mf sim` - reduce 50ms threshold to 6ms for reset to idle #1974 (@net147)
|
||||||
|
- Update `amiibo_tools.lua` with new identifiers and create a python script `update_amiibo_tools_lua.py` to automate the process in the future. (@CorySolovewicz)
|
||||||
|
|
||||||
## [Nitride.4.16191][2023-01-29]
|
## [Nitride.4.16191][2023-01-29]
|
||||||
- Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox)
|
- Changed `build_all_firmwares.sh` to fit GENERIC 256kb firmware images (@doegox)
|
||||||
|
|
|
@ -655,6 +655,7 @@ static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
|
|
||||||
if (bPwd && (bAuthenticating == false) && write) {
|
if (bPwd && (bAuthenticating == false) && write) {
|
||||||
|
SpinDelay(2);
|
||||||
if (hitag2_write_page(rx, rxlen, tx, txlen) == false) {
|
if (hitag2_write_page(rx, rxlen, tx, txlen) == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,9 @@ amiibo_tools.db =
|
||||||
["0x00000003039bff02"] = {
|
["0x00000003039bff02"] = {
|
||||||
name = "Mario - Power Up Band"
|
name = "Mario - Power Up Band"
|
||||||
},
|
},
|
||||||
|
["0x000000030430ff02"] = {
|
||||||
|
name = "Golden - Power Up Band"
|
||||||
|
},
|
||||||
["0x0000010000190002"] = {
|
["0x0000010000190002"] = {
|
||||||
name = "Dr. Mario"
|
name = "Dr. Mario"
|
||||||
},
|
},
|
||||||
|
@ -214,6 +217,9 @@ amiibo_tools.db =
|
||||||
["0x0100000003990902"] = {
|
["0x0100000003990902"] = {
|
||||||
name = "Link - Link's Awakening"
|
name = "Link - Link's Awakening"
|
||||||
},
|
},
|
||||||
|
["0x0100000004180902"] = {
|
||||||
|
name = "Link - Tears of the Kingdom"
|
||||||
|
},
|
||||||
["0x0100010000160002"] = {
|
["0x0100010000160002"] = {
|
||||||
name = "Toon Link"
|
name = "Toon Link"
|
||||||
},
|
},
|
||||||
|
@ -1834,6 +1840,9 @@ amiibo_tools.db =
|
||||||
["0x0800010003820002"] = {
|
["0x0800010003820002"] = {
|
||||||
name = "Inkling"
|
name = "Inkling"
|
||||||
},
|
},
|
||||||
|
["0x0800010004150402"] = {
|
||||||
|
name = "Inkling - Yellow"
|
||||||
|
},
|
||||||
["0x08000200003f0402"] = {
|
["0x08000200003f0402"] = {
|
||||||
name = "Inkling Boy"
|
name = "Inkling Boy"
|
||||||
},
|
},
|
||||||
|
@ -1870,9 +1879,15 @@ amiibo_tools.db =
|
||||||
["0x08050200038f0402"] = {
|
["0x08050200038f0402"] = {
|
||||||
name = "Octoling Boy"
|
name = "Octoling Boy"
|
||||||
},
|
},
|
||||||
|
["0x08050200041b0402"] = {
|
||||||
|
name = "Octoling - Blue"
|
||||||
|
},
|
||||||
["0x0805030003900402"] = {
|
["0x0805030003900402"] = {
|
||||||
name = "Octoling Octopus"
|
name = "Octoling Octopus"
|
||||||
},
|
},
|
||||||
|
["0x08060100041c0402"] = {
|
||||||
|
name = "Smallfry"
|
||||||
|
},
|
||||||
["0x09c0010102690e02"] = {
|
["0x09c0010102690e02"] = {
|
||||||
name = "Mario - Soccer"
|
name = "Mario - Soccer"
|
||||||
},
|
},
|
||||||
|
@ -2374,6 +2389,9 @@ amiibo_tools.db =
|
||||||
["0x3380000003781402"] = {
|
["0x3380000003781402"] = {
|
||||||
name = "Solaire of Astora"
|
name = "Solaire of Astora"
|
||||||
},
|
},
|
||||||
|
["0x33c0000004200002"] = {
|
||||||
|
name = "Kazuya"
|
||||||
|
},
|
||||||
["0x3480000000310002"] = {
|
["0x3480000000310002"] = {
|
||||||
name = "Mega Man"
|
name = "Mega Man"
|
||||||
},
|
},
|
||||||
|
@ -2455,6 +2473,9 @@ amiibo_tools.db =
|
||||||
["0x3600010003620002"] = {
|
["0x3600010003620002"] = {
|
||||||
name = "Cloud - Player 2"
|
name = "Cloud - Player 2"
|
||||||
},
|
},
|
||||||
|
["0x3601000004210002"] = {
|
||||||
|
name = "Sephiroth"
|
||||||
|
},
|
||||||
["0x3640000003a20002"] = {
|
["0x3640000003a20002"] = {
|
||||||
name = "Hero"
|
name = "Hero"
|
||||||
},
|
},
|
||||||
|
@ -2520,6 +2541,12 @@ amiibo_tools.db =
|
||||||
},
|
},
|
||||||
["0x3c80000003a40002"] = {
|
["0x3c80000003a40002"] = {
|
||||||
name = "Terry"
|
name = "Terry"
|
||||||
|
},
|
||||||
|
["0x3dc0000004220002"] = {
|
||||||
|
name = "Steve"
|
||||||
|
},
|
||||||
|
["0x3dc1000004230002"] = {
|
||||||
|
name = "Alex"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
game_series = {
|
game_series = {
|
||||||
|
@ -2621,6 +2648,7 @@ amiibo_tools.db =
|
||||||
["0x324"] = "Bayonetta",
|
["0x324"] = "Bayonetta",
|
||||||
["0x334"] = "Pac-man",
|
["0x334"] = "Pac-man",
|
||||||
["0x338"] = "Dark Souls",
|
["0x338"] = "Dark Souls",
|
||||||
|
["0x33c"] = "Tekken",
|
||||||
["0x348"] = "Megaman",
|
["0x348"] = "Megaman",
|
||||||
["0x34c"] = "Street fighter",
|
["0x34c"] = "Street fighter",
|
||||||
["0x350"] = "Monster Hunter",
|
["0x350"] = "Monster Hunter",
|
||||||
|
@ -2635,7 +2663,8 @@ amiibo_tools.db =
|
||||||
["0x38c"] = "Diablo",
|
["0x38c"] = "Diablo",
|
||||||
["0x3a0"] = "Persona",
|
["0x3a0"] = "Persona",
|
||||||
["0x3b4"] = "Banjo Kazooie",
|
["0x3b4"] = "Banjo Kazooie",
|
||||||
["0x3c8"] = "Fatal Fury"
|
["0x3c8"] = "Fatal Fury",
|
||||||
|
["0x3dc"] = "Minecraft"
|
||||||
},
|
},
|
||||||
types = {
|
types = {
|
||||||
["0x00"] = "Figure",
|
["0x00"] = "Figure",
|
||||||
|
|
|
@ -1109,7 +1109,7 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
"Restore MIFARE Classic dump file to tag.\n"
|
"Restore MIFARE Classic dump file to tag.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"The key file and dump file will program the card sector trailers.\n"
|
"The key file and dump file will program the card sector trailers.\n"
|
||||||
"By default we authenticate to card with key B 0xFFFFFFFFFFFF.\n"
|
"By default we authenticate to card with key 0xFFFFFFFFFFFF.\n"
|
||||||
"If access rights in dump file is all zeros, it will be replaced with default values\n"
|
"If access rights in dump file is all zeros, it will be replaced with default values\n"
|
||||||
"\n"
|
"\n"
|
||||||
"`--uid` param is used for filename templates `hf-mf-<uid>-dump.bin` and `hf-mf-<uid>-key.bin.\n"
|
"`--uid` param is used for filename templates `hf-mf-<uid>-dump.bin` and `hf-mf-<uid>-key.bin.\n"
|
||||||
|
@ -1321,14 +1321,16 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
uint8_t wdata[26];
|
uint8_t wdata[26];
|
||||||
memcpy(wdata + 10, bldata, sizeof(bldata));
|
memcpy(wdata + 10, bldata, sizeof(bldata));
|
||||||
|
|
||||||
if (use_keyfile_for_auth) {
|
|
||||||
for (int8_t kt = MF_KEY_B; kt > -1; kt--) {
|
for (int8_t kt = MF_KEY_B; kt > -1; kt--) {
|
||||||
|
if (use_keyfile_for_auth) {
|
||||||
if (kt == MF_KEY_A)
|
if (kt == MF_KEY_A)
|
||||||
memcpy(wdata, keyA[s], 6);
|
memcpy(wdata, keyA[s], 6);
|
||||||
else
|
else
|
||||||
memcpy(wdata, keyB[s], 6);
|
memcpy(wdata, keyB[s], 6);
|
||||||
|
} else {
|
||||||
|
// use default key to authenticate for the write command
|
||||||
|
memcpy(wdata, default_key, 6);
|
||||||
|
}
|
||||||
PrintAndLogEx(INFO, "block %3d: %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata)));
|
PrintAndLogEx(INFO, "block %3d: %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata)));
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -1350,27 +1352,6 @@ static int CmdHF14AMfRestore(const char *Cmd) {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
PrintAndLogEx(WARNING, "Command execute timeout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// use default key to authenticate for the write command
|
|
||||||
memcpy(wdata, default_key, 6);
|
|
||||||
PrintAndLogEx(INFO, "block %3d: %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata)));
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, mfFirstBlockOfSector(s) + b, MF_KEY_B, 0, wdata, sizeof(wdata));
|
|
||||||
PacketResponseNG resp;
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
|
||||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
|
||||||
if (isOK == 0) {
|
|
||||||
if (b == 0) {
|
|
||||||
PrintAndLogEx(INFO, "Writing to manufacture block w key B ( " _RED_("fail") " )");
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(FAILED, "Write to block %u w key B ( " _RED_("fail") " )", b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
|
||||||
}
|
|
||||||
} // end use_keyfile_for_auth
|
|
||||||
} // end loop B
|
} // end loop B
|
||||||
} // end loop S
|
} // end loop S
|
||||||
|
|
||||||
|
|
|
@ -2690,7 +2690,7 @@ static void wait4response(uint8_t b) {
|
||||||
int CmdHF14MfUTamper(const char *Cmd) {
|
int CmdHF14MfUTamper(const char *Cmd) {
|
||||||
CLIParserContext *ctx;
|
CLIParserContext *ctx;
|
||||||
CLIParserInit(&ctx, "hf mfu tamper",
|
CLIParserInit(&ctx, "hf mfu tamper",
|
||||||
"Set the congiguration of the NTAG 213TT tamper feature\n"
|
"Set the configuration of the NTAG 213TT tamper feature\n"
|
||||||
"Supports:\n"
|
"Supports:\n"
|
||||||
"NTAG 213TT\n",
|
"NTAG 213TT\n",
|
||||||
"hf mfu tamper -e -> enable tamper feature\n"
|
"hf mfu tamper -e -> enable tamper feature\n"
|
||||||
|
@ -4697,7 +4697,7 @@ static command_t CommandTable[] = {
|
||||||
{"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"},
|
{"restore", CmdHF14AMfURestore, IfPm3Iso14443a, "Restore a dump onto a MFU MAGIC tag"},
|
||||||
{"view", CmdHF14AMfuView, AlwaysAvailable, "Display content from tag dump file"},
|
{"view", CmdHF14AMfuView, AlwaysAvailable, "Display content from tag dump file"},
|
||||||
{"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"},
|
{"wrbl", CmdHF14AMfUWrBl, IfPm3Iso14443a, "Write block"},
|
||||||
{"tamper", CmdHF14MfUTamper, IfPm3Iso14443a, "Cofigure the tamper feature on an NTAG 213TT"},
|
{"tamper", CmdHF14MfUTamper, IfPm3Iso14443a, "Configure the tamper feature on an NTAG 213TT"},
|
||||||
{"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
|
{"---------", CmdHelp, IfPm3Iso14443a, "----------------------- " _CYAN_("simulation") " -----------------------"},
|
||||||
{"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "Load Ultralight dump file into emulator memory"},
|
{"eload", CmdHF14AMfUeLoad, IfPm3Iso14443a, "Load Ultralight dump file into emulator memory"},
|
||||||
{"esave", CmdHF14AMfuESave, IfPm3Iso14443a, "Save Ultralight dump file from emulator memory"},
|
{"esave", CmdHF14AMfuESave, IfPm3Iso14443a, "Save Ultralight dump file from emulator memory"},
|
||||||
|
|
114
client/update_amiibo_tools_lua.py
Normal file
114
client/update_amiibo_tools_lua.py
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Name: update_amiibo_tools_lua.py
|
||||||
|
|
||||||
|
Author: Cory Solovewicz
|
||||||
|
|
||||||
|
Description:
|
||||||
|
This is a python script to automate what the updating of the amiibo_tools.lua
|
||||||
|
file which holds a lua table of all known amiibos. Previously updating the
|
||||||
|
amiibo_tools.lua was a very manual process.
|
||||||
|
|
||||||
|
This script automates the following original command:
|
||||||
|
curl https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/database/amiibo.json | jq 'del(.amiibos[].release)' | jq 'del(.characters)' | pbcopy --> transform to table
|
||||||
|
And outputs the formatted file as amiibo_tools.lua
|
||||||
|
If everything goes well, this should be an updated copy of amiibo_tools.lua
|
||||||
|
which can then be placed in the /lualibs/ directory.
|
||||||
|
The temporary amiibo.json file is then deleted
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
python3 -m pip install jq
|
||||||
|
|
||||||
|
How to run:
|
||||||
|
python update_amiibo_tools_lua.py
|
||||||
|
The script will create the file amiibo_tools.lua
|
||||||
|
|
||||||
|
After running, manually backup the original /lualibs/amiibo_tools.lua and move the
|
||||||
|
updated amiibo_tools.lua to the /lualibs/ directory.
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
from jq import jq
|
||||||
|
|
||||||
|
def fetch_data():
|
||||||
|
print("Fetching amiibo.json")
|
||||||
|
# Perform the curl command
|
||||||
|
curl_command = "curl https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/database/amiibo.json"
|
||||||
|
curl_process = subprocess.Popen(curl_command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
output, error = curl_process.communicate()
|
||||||
|
|
||||||
|
if curl_process.returncode != 0:
|
||||||
|
print("Error fetching data: ", error.decode())
|
||||||
|
return None
|
||||||
|
return output
|
||||||
|
|
||||||
|
def filter_data(data):
|
||||||
|
print("Filtering downloaded data")
|
||||||
|
# Convert the output to JSON and use jq to filter data
|
||||||
|
data_json = json.loads(data)
|
||||||
|
filtered_data_json = jq('del(.amiibos[].release) | del(.characters)').transform(data_json)
|
||||||
|
# Convert the filtered JSON data back to a string, preserving Unicode characters
|
||||||
|
filtered_data = json.dumps(filtered_data_json, indent=2, ensure_ascii=False)
|
||||||
|
return filtered_data
|
||||||
|
|
||||||
|
def save_data(filtered_data, filename):
|
||||||
|
# Save filtered data to file
|
||||||
|
with open(filename, 'w', encoding='utf-8') as file:
|
||||||
|
file.write(filtered_data)
|
||||||
|
print(f"Data saved to {filename}")
|
||||||
|
|
||||||
|
def process_file(filename):
|
||||||
|
# Open the file
|
||||||
|
with open(filename, 'r', encoding='utf-8') as file:
|
||||||
|
data = file.read()
|
||||||
|
|
||||||
|
# Perform the replacements
|
||||||
|
data = data.replace('"name"', 'name')
|
||||||
|
data = data.replace('"amiibo_series"', 'amiibo_series')
|
||||||
|
data = data.replace('"amiibos"', 'amiibos')
|
||||||
|
data = data.replace('"game_series"', 'game_series')
|
||||||
|
data = data.replace('"types"', 'types')
|
||||||
|
data = data.replace(':', ' =')
|
||||||
|
data = re.sub('"0x', '["0x', data)
|
||||||
|
data = re.sub('" =', '"] =', data)
|
||||||
|
|
||||||
|
# Prepend the text
|
||||||
|
prepend_text = 'local amiibo_tools = {}\n\n-- curl https://raw.githubusercontent.com/N3evin/AmiiboAPI/master/database/amiibo.json | jq \'del(.amiibos[].release)\' | jq \'del(.characters)\' | pbcopy --> transform to table\namiibo_tools.db =\n'
|
||||||
|
data = prepend_text + data
|
||||||
|
|
||||||
|
# Append the text
|
||||||
|
append_text = '\n\nreturn amiibo_tools\n'
|
||||||
|
data = data + append_text
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
def write_to_file(data, filename):
|
||||||
|
# Write the output
|
||||||
|
with open(filename, 'w', encoding='utf-8') as file:
|
||||||
|
file.write(data)
|
||||||
|
print(f"Output written to {filename}")
|
||||||
|
|
||||||
|
def delete_file(filename):
|
||||||
|
try:
|
||||||
|
os.remove(filename)
|
||||||
|
print(f"Temporary file {filename} deleted")
|
||||||
|
except OSError as e:
|
||||||
|
print(f"Error deleting file {filename}: ", e)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
data = fetch_data()
|
||||||
|
if data:
|
||||||
|
filtered_data = filter_data(data)
|
||||||
|
save_data(filtered_data, 'amiibo.json')
|
||||||
|
processed_data = process_file('amiibo.json')
|
||||||
|
write_to_file(processed_data, 'amiibo_tools.lua')
|
||||||
|
delete_file('amiibo.json')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Loading…
Add table
Add a link
Reference in a new issue