mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
commit
440c5ac1fa
16 changed files with 333 additions and 72 deletions
|
@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Changed `hf mf sim` - reduce 6ms threshold to 4ms for reset to idle #1974 (@net147)
|
||||||
|
- Rebuilt the Spartan-2 `fpga_*.bit` files to include the `hi_iso14443a.v` update (@d18c7db)
|
||||||
|
- Added minor orphaned change from `hi_iso14443a.v` in `fpga-xc3s100e` to `hi_iso14443a.v` in `fpga-xc2s30` (@d18c7db)
|
||||||
|
- 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)
|
||||||
|
@ -61,6 +66,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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2097,8 +2097,8 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) {
|
||||||
if (timer == 0) {
|
if (timer == 0) {
|
||||||
timer = GetTickCount();
|
timer = GetTickCount();
|
||||||
} else {
|
} else {
|
||||||
// 6ms no field --> card to idle state
|
// 4ms no field --> card to idle state
|
||||||
if (GetTickCountDelta(timer) > 6) {
|
if (GetTickCountDelta(timer) > 4) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2150,3 +2150,7 @@ D201DBB6AB6E
|
||||||
# Data from Discord, French pool
|
# Data from Discord, French pool
|
||||||
9B7C25052FC3
|
9B7C25052FC3
|
||||||
494446555455
|
494446555455
|
||||||
|
#
|
||||||
|
# Data from Discord, seems to be related to ASSA
|
||||||
|
427553754D47
|
||||||
|
|
||||||
|
|
|
@ -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",
|
||||||
|
|
112
client/pyscripts/pm3_nfc2eml.py
Executable file
112
client/pyscripts/pm3_nfc2eml.py
Executable file
|
@ -0,0 +1,112 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Script to convert amiibo nfc Flipper Zero files to eml files to be used with Proxmark3
|
||||||
|
Date: 18/05/2023
|
||||||
|
Script Author: OscarAkaElvis
|
||||||
|
Tested on: Linux and Windows
|
||||||
|
OscarAkaElvis - https://twitter.com/OscarAkaElvis
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
from os import path
|
||||||
|
from sys import argv
|
||||||
|
|
||||||
|
# Vars
|
||||||
|
script_name = path.basename(argv[0])
|
||||||
|
script_version = "1.0"
|
||||||
|
|
||||||
|
# Function to print script's version
|
||||||
|
def print_version():
|
||||||
|
print()
|
||||||
|
return 'v{}'.format(script_version)
|
||||||
|
|
||||||
|
# Check if the input file is a text file based on its content
|
||||||
|
def is_text_file(file_path):
|
||||||
|
with open(file_path, 'rb') as file:
|
||||||
|
try:
|
||||||
|
file_content = file.read().decode('utf-8')
|
||||||
|
return all(ord(char) < 128 for char in file_content)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Main script code
|
||||||
|
def main():
|
||||||
|
# Text help data
|
||||||
|
description_text = "Script to convert amiibo nfc Flipper Zero files to eml files to be used with Proxmark3."
|
||||||
|
epilog_text = 'Example:\n python3 ' + script_name + ' -i file.nfc -o output.eml'
|
||||||
|
|
||||||
|
# Create an argument parser
|
||||||
|
parser = argparse.ArgumentParser(exit_on_error=False, description=description_text, formatter_class=argparse.RawDescriptionHelpFormatter, epilog=epilog_text)
|
||||||
|
# Add the input file argument
|
||||||
|
parser.add_argument("-i", "--input", required=True, help="Path to the input nfc file.")
|
||||||
|
# Add the output file argument
|
||||||
|
parser.add_argument("-o", "--output", required=True, help="Name of the output eml file.")
|
||||||
|
# Add the version argument
|
||||||
|
parser.add_argument('-v', '--version', action='version', version=print_version(), help="Show script's version number and exit")
|
||||||
|
|
||||||
|
# Parse the command-line arguments
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Extract the file paths from the command-line arguments
|
||||||
|
file_path = args.input
|
||||||
|
output_file = args.output
|
||||||
|
|
||||||
|
# Check if the target file exists
|
||||||
|
if not os.path.isfile(file_path):
|
||||||
|
print(f"[!] The input file '{file_path}' does not exist.")
|
||||||
|
exit(0)
|
||||||
|
|
||||||
|
# Validation to check if the input file is a text file based on its content
|
||||||
|
if not is_text_file(file_path):
|
||||||
|
print("[!] The input file does not appear to be a nfc text file.")
|
||||||
|
|
||||||
|
# Check if the input file name has the .nfc extension
|
||||||
|
if not file_path.lower().endswith('.nfc'):
|
||||||
|
print("[+] Warning. The input file should have the '.nfc' extension.")
|
||||||
|
|
||||||
|
# Get the absolute path of the output file
|
||||||
|
output_file_path = os.path.abspath(output_file)
|
||||||
|
|
||||||
|
# Check if the directory of the output file is writable
|
||||||
|
output_dir = os.path.dirname(output_file_path)
|
||||||
|
if not os.access(output_dir, os.W_OK):
|
||||||
|
print(f"[!] The output directory '{output_dir}' is not writable or doesn't exist.")
|
||||||
|
|
||||||
|
# Check if the output file name has the .eml extension
|
||||||
|
if not output_file.lower().endswith('.eml'):
|
||||||
|
print("[+] Warning. The output file should have the '.eml' extension.")
|
||||||
|
|
||||||
|
# Read the target file
|
||||||
|
with open(file_path, 'r') as file:
|
||||||
|
file_content = file.read()
|
||||||
|
|
||||||
|
# Extract the data from each "Page X" line
|
||||||
|
matches = re.findall(r'Page \d+:(.*?)$', file_content, re.MULTILINE | re.DOTALL)
|
||||||
|
|
||||||
|
if matches:
|
||||||
|
# Remove spaces and convert to lowercase for each match
|
||||||
|
extracted_data = [re.sub(r'\s', '', match).lower() for match in matches]
|
||||||
|
|
||||||
|
# Join the extracted data with line feeds
|
||||||
|
result = '\n'.join(extracted_data)
|
||||||
|
|
||||||
|
# Write the extracted data to the output file
|
||||||
|
with open(output_file_path, 'w', newline='\n') as output_file:
|
||||||
|
output_file.write(result)
|
||||||
|
print(f"[*] File converted successfully. Output eml file written as '{os.path.basename(output_file.name)}'.")
|
||||||
|
else:
|
||||||
|
# If the needed data is not there
|
||||||
|
print("[!] Provided input file seems to not be a valid nfc file to work with.")
|
||||||
|
|
||||||
|
# Application entrypoint
|
||||||
|
if __name__ == '__main__':
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
|
@ -137,15 +137,14 @@ static char *GenerateFilename(const char *prefix, const char *suffix) {
|
||||||
static int initSectorTable(sector_t **src, size_t items) {
|
static int initSectorTable(sector_t **src, size_t items) {
|
||||||
|
|
||||||
(*src) = calloc(items, sizeof(sector_t));
|
(*src) = calloc(items, sizeof(sector_t));
|
||||||
|
|
||||||
if (*src == NULL)
|
if (*src == NULL)
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
|
|
||||||
// empty e_sector
|
// empty e_sector
|
||||||
for (int i = 0; i < items; ++i) {
|
for (int i = 0; i < items; i++) {
|
||||||
for (int j = 0; j < 2; ++j) {
|
for (int j = 0; j < 2; j++) {
|
||||||
(*src)[i].Key[j] = 0xffffffffffff;
|
(*src)[i].Key[j] = 0xffffffffffff;
|
||||||
(*src)[i].foundKey[j] = false;
|
(*src)[i].foundKey[j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -1109,7 +1108,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,56 +1320,37 @@ 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 {
|
||||||
PrintAndLogEx(INFO, "block %3d: %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata)));
|
// use default key to authenticate for the write command
|
||||||
|
memcpy(wdata, default_key, 6);
|
||||||
clearCommandBuffer();
|
|
||||||
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, mfFirstBlockOfSector(s) + b, kt, 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 %c ( " _RED_("fail") " )", (kt == MF_KEY_A) ? 'A' : 'B');
|
|
||||||
} else {
|
|
||||||
PrintAndLogEx(FAILED, "Write to block %u w key %c ( " _RED_("fail") " ) ", b, (kt == MF_KEY_A) ? 'A' : 'B');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if success, skip to next block
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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)));
|
PrintAndLogEx(INFO, "block %3d: %s", mfFirstBlockOfSector(s) + b, sprint_hex(bldata, sizeof(bldata)));
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, mfFirstBlockOfSector(s) + b, MF_KEY_B, 0, wdata, sizeof(wdata));
|
SendCommandMIX(CMD_HF_MIFARE_WRITEBL, mfFirstBlockOfSector(s) + b, kt, 0, wdata, sizeof(wdata));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
uint8_t isOK = resp.oldarg[0] & 0xff;
|
uint8_t isOK = resp.oldarg[0] & 0xff;
|
||||||
if (isOK == 0) {
|
if (isOK == 0) {
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
PrintAndLogEx(INFO, "Writing to manufacture block w key B ( " _RED_("fail") " )");
|
PrintAndLogEx(INFO, "Writing to manufacture block w key %c ( " _RED_("fail") " )", (kt == MF_KEY_A) ? 'A' : 'B');
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(FAILED, "Write to block %u w key B ( " _RED_("fail") " )", b);
|
PrintAndLogEx(FAILED, "Write to block %u w key %c ( " _RED_("fail") " ) ", b, (kt == MF_KEY_A) ? 'A' : 'B');
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// if success, skip to next block
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Command execute timeout");
|
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"},
|
||||||
|
|
|
@ -43,10 +43,36 @@
|
||||||
|
|
||||||
static const uint64_t g_mifare_default_keys[] = {
|
static const uint64_t g_mifare_default_keys[] = {
|
||||||
0xffffffffffff, // Default key (first key used by program if no user defined key)
|
0xffffffffffff, // Default key (first key used by program if no user defined key)
|
||||||
0x000000000000, // Blank key
|
|
||||||
0xa0a1a2a3a4a5, // NFCForum MAD key
|
0xa0a1a2a3a4a5, // NFCForum MAD key
|
||||||
0xd3f7d3f7d3f7, // NDEF public key
|
0xd3f7d3f7d3f7, // NDEF public key
|
||||||
0x4b791bea7bcc, // MFC EV1 Signature B
|
0x4b791bea7bcc, // MFC EV1 Signature B
|
||||||
|
0xfc00018778f7, // Public Transport
|
||||||
|
0x6471a5ef2d1a, // SimonsVoss
|
||||||
|
0x4E3552426B32, // ID06
|
||||||
|
0x6A1987C40A21, // Salto
|
||||||
|
0xef1232ab18a0, // Schlage
|
||||||
|
0x3B7E4FD575AD, //
|
||||||
|
0xb7bf0c13066e, // Gallagher
|
||||||
|
0x135b88a94b8b, // Saflok
|
||||||
|
0x2A2C13CC242A, // Dorma Kaba
|
||||||
|
0x5a7a52d5e20d, // Bosch
|
||||||
|
0x314B49474956, // VIGIK1 A
|
||||||
|
0x564c505f4d41, // VIGIK1 B
|
||||||
|
0x021209197591, // BTCINO
|
||||||
|
0x484558414354, // Intratone
|
||||||
|
0xEC0A9B1A9E06, // Vingcard
|
||||||
|
0x66b31e64ca4b, // Vingcard
|
||||||
|
0x97F5DA640B18, // Bangkok metro key
|
||||||
|
0xA8844B0BCA06, // Metro Valencia key
|
||||||
|
0xE4410EF8ED2D, // Armenian metro
|
||||||
|
0x857464D3AAD1, // HTC Eindhoven key
|
||||||
|
0x08B386463229, // troika
|
||||||
|
0xe00000000000, // icopy
|
||||||
|
0x199404281970, // NSP A
|
||||||
|
0x199404281998, // NSP B
|
||||||
|
0x6A1987C40A21, // SALTO
|
||||||
|
0x7F33625BC129, // SALTO
|
||||||
|
0x000000000000, // Blank key
|
||||||
0xb0b1b2b3b4b5,
|
0xb0b1b2b3b4b5,
|
||||||
0xaabbccddeeff,
|
0xaabbccddeeff,
|
||||||
0x1a2b3c4d5e6f,
|
0x1a2b3c4d5e6f,
|
||||||
|
@ -64,29 +90,6 @@ static const uint64_t g_mifare_default_keys[] = {
|
||||||
0x0000014b5c31,
|
0x0000014b5c31,
|
||||||
0xb578f38a5c61,
|
0xb578f38a5c61,
|
||||||
0x96a301bce267,
|
0x96a301bce267,
|
||||||
0xfc00018778f7, // Public Transport
|
|
||||||
0x6471a5ef2d1a, // SimonsVoss
|
|
||||||
0x4E3552426B32, // ID06
|
|
||||||
0x6A1987C40A21, // Salto
|
|
||||||
0xef1232ab18a0, // Schlage
|
|
||||||
0x3B7E4FD575AD, //
|
|
||||||
0xb7bf0c13066e, // Gallagher
|
|
||||||
0x135b88a94b8b, // Saflock
|
|
||||||
0x5a7a52d5e20d, // Bosch
|
|
||||||
0x314B49474956, // VIGIK1 A
|
|
||||||
0x564c505f4d41, // VIGIK1 B
|
|
||||||
0x021209197591, // BTCINO
|
|
||||||
0x484558414354, // Intratone
|
|
||||||
0xEC0A9B1A9E06, // Vingcard
|
|
||||||
0x66b31e64ca4b, // Vingcard
|
|
||||||
0x97F5DA640B18, // Bangkok metro key
|
|
||||||
0xA8844B0BCA06, // Metro Valencia key
|
|
||||||
0xE4410EF8ED2D, // Armenian metro
|
|
||||||
0x857464D3AAD1, // HTC Eindhoven key
|
|
||||||
0x08B386463229, // troika
|
|
||||||
0xe00000000000, // icopy
|
|
||||||
0x199404281970, // NSP A
|
|
||||||
0x199404281998, // NSP B
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t g_mifare_default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
static const uint8_t g_mifare_default_key[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
|
|
|
@ -923,7 +923,7 @@ static int ndefDecodeExternal_record(NDEFHeader_t *ndef) {
|
||||||
);
|
);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "Payload [%u]...", ndef->PayloadLen);
|
PrintAndLogEx(INFO, "Payload [%zu]...", ndef->PayloadLen);
|
||||||
print_hex_noascii_break(ndef->Payload, ndef->PayloadLen, 32);
|
print_hex_noascii_break(ndef->Payload, ndef->PayloadLen, 32);
|
||||||
|
|
||||||
// do a character check?
|
// do a character check?
|
||||||
|
|
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()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -222,17 +222,29 @@ reg signed [10:0] rx_mod_falling_edge_max;
|
||||||
reg signed [10:0] rx_mod_rising_edge_max;
|
reg signed [10:0] rx_mod_rising_edge_max;
|
||||||
reg curbit;
|
reg curbit;
|
||||||
|
|
||||||
`define EDGE_DETECT_THRESHOLD 5
|
`define EDGE_DETECT_THRESHOLD 3
|
||||||
|
`define EDGE_DETECT_THRESHOLDHIGH 20
|
||||||
|
|
||||||
always @(negedge adc_clk)
|
always @(negedge adc_clk)
|
||||||
begin
|
begin
|
||||||
if(negedge_cnt[3:0] == mod_detect_reset_time)
|
if(negedge_cnt[3:0] == mod_detect_reset_time)
|
||||||
begin
|
begin
|
||||||
// detect modulation signal: if modulating, there must have been a falling AND a rising edge
|
if (mod_type == `FPGA_HF_ISO14443A_SNIFFER)
|
||||||
if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD))
|
begin
|
||||||
curbit <= 1'b1; // modulation
|
// detect modulation signal: if modulating, there must have been a falling AND a rising edge
|
||||||
else
|
if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLDHIGH) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLDHIGH))
|
||||||
curbit <= 1'b0; // no modulation
|
curbit <= 1'b1; // modulation
|
||||||
|
else
|
||||||
|
curbit <= 1'b0; // no modulation
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// detect modulation signal: if modulating, there must have been a falling AND a rising edge
|
||||||
|
if ((rx_mod_falling_edge_max > `EDGE_DETECT_THRESHOLD) && (rx_mod_rising_edge_max < -`EDGE_DETECT_THRESHOLD))
|
||||||
|
curbit <= 1'b1; // modulation
|
||||||
|
else
|
||||||
|
curbit <= 1'b0; // no modulation
|
||||||
|
end
|
||||||
// reset modulation detector
|
// reset modulation detector
|
||||||
rx_mod_rising_edge_max <= 0;
|
rx_mod_rising_edge_max <= 0;
|
||||||
rx_mod_falling_edge_max <= 0;
|
rx_mod_falling_edge_max <= 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue