mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
Merge branch 'master' into smart_spi_detect
Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
commit
4cd914ad95
11 changed files with 437 additions and 80 deletions
|
@ -4,7 +4,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
|
||||
## [unreleased][unreleased]
|
||||
- Changed SPI flash detection to calculate the size instead of table lookup, updated spi_flash_decode.py script with more ICs (@ANTodorov)
|
||||
- Add option to set and get maximum read/write block number using `hf_mf_ultimatecard` script (@piotrva)
|
||||
- Fixed `hf/lf tune` segfault when called from script (@doegox)
|
||||
- Added option to set and get maximum read/write block number using `hf_mf_ultimatecard` script (@piotrva)
|
||||
- Added JEDEC information for SPI flash W25Q64JV (@ANTodorov)
|
||||
- Added special iclass legacy config cards in `hf iclass configcard` (@antiklesys)
|
||||
- Added simulation function to `hf iclass legrec` (@antiklesys)
|
||||
|
|
|
@ -3482,7 +3482,8 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
|
|||
retval = PM3_ESOFT;
|
||||
goto OUT;
|
||||
}
|
||||
cmd[ofs++] = card_info->sak;
|
||||
cmd[ofs] = block_len <= card_info->uidlen ? card_info->sak : cmd[ofs];
|
||||
ofs++;
|
||||
cmd[ofs++] = card_info->atqa[0];
|
||||
cmd[ofs++] = card_info->atqa[1];
|
||||
AddCrc14A(cmd, sizeof(block_cmd) + MIFARE_BLOCK_SIZE);
|
||||
|
|
|
@ -2760,3 +2760,6 @@ D37C8F1793F7
|
|||
56cf3acd90ca
|
||||
542089792be2
|
||||
5420aeada758
|
||||
#CSC Laundry
|
||||
212223242555
|
||||
717273747555
|
||||
|
|
|
@ -1,81 +1,177 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
### Parameters
|
||||
import os
|
||||
import subprocess
|
||||
import signal
|
||||
import numpy as np
|
||||
from pyaudio import PyAudio, paFloat32, paContinue
|
||||
|
||||
# Sound output parameters
|
||||
volume = 1.0
|
||||
sample_buf_size = 44
|
||||
sampling_freq = 44100 #Hz
|
||||
sampling_freq = 44100 # Hz
|
||||
|
||||
# Frequency generator parameters
|
||||
min_freq = 200 #Hz
|
||||
max_freq = 2000 #Hz
|
||||
min_freq = 100 # Hz
|
||||
max_freq = 6000 # Hz
|
||||
|
||||
# Proxmark3 parameters
|
||||
pm3_client="/usr/local/bin/proxmark3"
|
||||
pm3_reader_dev_file="/dev/ttyACM0"
|
||||
pm3_tune_cmd="hf tune"
|
||||
pm3_client = "pm3"
|
||||
pm3_tune_cmd = "hf tune --value"
|
||||
|
||||
frequency = 440
|
||||
buffer = []
|
||||
|
||||
|
||||
### Modules
|
||||
import numpy
|
||||
import pyaudio
|
||||
from select import select
|
||||
from subprocess import Popen, DEVNULL, PIPE
|
||||
def find_zero_crossing_index(array):
|
||||
for i in range(1, len(array)):
|
||||
if array[i-1] < 0 and array[i] >= 0:
|
||||
return i
|
||||
return None # Return None if no zero-crossing is found
|
||||
|
||||
|
||||
### Main program
|
||||
p = pyaudio.PyAudio()
|
||||
def generate_sine_wave(frequency, sample_rate, duration, frame_count):
|
||||
"""Generate a sine wave at a given frequency."""
|
||||
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
|
||||
wave = np.sin(2 * np.pi * frequency * t)
|
||||
return wave[:frame_count]
|
||||
|
||||
# For paFloat32 sample values must be in range [-1.0, 1.0]
|
||||
stream = p.open(format=pyaudio.paFloat32,
|
||||
channels=1,
|
||||
rate=sampling_freq,
|
||||
output=True)
|
||||
|
||||
# Initial voltage to frequency values
|
||||
min_v = 100.0
|
||||
max_v = 0.0
|
||||
v = 0
|
||||
out_freq = min_freq
|
||||
# PyAudio Callback function
|
||||
def pyaudio_callback(in_data, frame_count, time_info, status):
|
||||
# if in_data is None:
|
||||
# return (in_data, pyaudio.paContinue)
|
||||
global frequency
|
||||
global buffer
|
||||
wave = generate_sine_wave(frequency, sampling_freq, 0.01, frame_count*2)
|
||||
i = find_zero_crossing_index(buffer)
|
||||
if i is None:
|
||||
buffer = wave
|
||||
else:
|
||||
buffer = np.concatenate((buffer[:i], wave))
|
||||
data = (buffer[:frame_count] * volume).astype(np.float32).tobytes()
|
||||
buffer = buffer[frame_count:]
|
||||
return (data, paContinue)
|
||||
# pyaudio.paComplete
|
||||
|
||||
# Spawn the Proxmark3 client
|
||||
pm3_proc = Popen([pm3_client, pm3_reader_dev_file, "-c", pm3_tune_cmd], bufsize=0, env={}, stdin=DEVNULL, stdout=PIPE, stderr=DEVNULL)
|
||||
mv_recbuf = ""
|
||||
|
||||
# Read voltages from the Proxmark3, generate the sine wave, output to soundcard
|
||||
sample_buf = [0.0 for x in range(0, sample_buf_size)]
|
||||
i = 0
|
||||
sinev = 0
|
||||
while True:
|
||||
def silent_pyaudio():
|
||||
"""
|
||||
Lifted and adapted from https://stackoverflow.com/questions/67765911/
|
||||
PyAudio is noisy af every time you initialise it, which makes reading the
|
||||
log output rather difficult. The output appears to be being made by the
|
||||
C internals, so we can't even redirect the logs with Python's logging
|
||||
facility. Therefore the nuclear option was selected: swallow all stderr
|
||||
and stdout for the duration of PyAudio's use.
|
||||
"""
|
||||
|
||||
# Read Proxmark3 client's stdout and extract voltage values
|
||||
if(select([pm3_proc.stdout], [], [], 0)[0]):
|
||||
# Open a pair of null files
|
||||
null_fds = [os.open(os.devnull, os.O_RDWR) for x in range(2)]
|
||||
# Save the actual stdout (1) and stderr (2) file descriptors.
|
||||
save_fds = [os.dup(1), os.dup(2)]
|
||||
# Assign the null pointers to stdout and stderr.
|
||||
os.dup2(null_fds[0], 1)
|
||||
os.dup2(null_fds[1], 2)
|
||||
pyaudio = PyAudio()
|
||||
os.dup2(save_fds[0], 1)
|
||||
os.dup2(save_fds[1], 2)
|
||||
# Close all file descriptors
|
||||
for fd in null_fds + save_fds:
|
||||
os.close(fd)
|
||||
return pyaudio
|
||||
|
||||
b = pm3_proc.stdout.read(256).decode("ascii")
|
||||
if "Done" in b:
|
||||
break;
|
||||
for c in b:
|
||||
if c in "0123456789 mV":
|
||||
mv_recbuf += c
|
||||
else:
|
||||
mv_recbuf = ""
|
||||
if mv_recbuf[-3:] == " mV":
|
||||
v = int(mv_recbuf[:-3]) / 1000
|
||||
if v < min_v:
|
||||
min_v = v - 0.001
|
||||
if v > max_v:
|
||||
max_v = v
|
||||
|
||||
def run_pm3_cmd(callback):
|
||||
# Start the process
|
||||
process = subprocess.Popen(
|
||||
[pm3_client, '-c', pm3_tune_cmd],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
bufsize=1, # Line buffered
|
||||
shell=False
|
||||
)
|
||||
|
||||
# Read the output line by line as it comes
|
||||
try:
|
||||
with process.stdout as pipe:
|
||||
for line in pipe:
|
||||
# Process each line
|
||||
l = line.strip() # Strip to remove any extraneous newline characters
|
||||
callback(l)
|
||||
except Exception as e:
|
||||
print(f"An error occurred: {e}")
|
||||
finally:
|
||||
# Ensure the subprocess is properly terminated
|
||||
process.terminate()
|
||||
process.wait()
|
||||
|
||||
|
||||
def linear_to_exponential_freq(v, min_v, max_v, min_freq, max_freq):
|
||||
# First, map v to a range between 0 and 1
|
||||
if max_v != min_v:
|
||||
normalized_v = (v - min_v) / (max_v - min_v)
|
||||
else:
|
||||
normalized_v = 0.5
|
||||
normalized_v = 1 - normalized_v
|
||||
|
||||
# Calculate the ratio of the max frequency to the min frequency
|
||||
freq_ratio = max_freq / min_freq
|
||||
|
||||
# Calculate the exponential frequency using the mapped v
|
||||
freq = min_freq * (freq_ratio ** normalized_v)
|
||||
return freq
|
||||
|
||||
|
||||
class foo():
|
||||
def __init__(self):
|
||||
self.p = silent_pyaudio()
|
||||
# For paFloat32 sample values must be in range [-1.0, 1.0]
|
||||
self.stream = self.p.open(format=paFloat32,
|
||||
channels=1,
|
||||
rate=sampling_freq,
|
||||
output=True,
|
||||
stream_callback=pyaudio_callback)
|
||||
|
||||
# Initial voltage to frequency values
|
||||
self.min_v = 50000.0
|
||||
self.max_v = 0.0
|
||||
|
||||
# Setting the signal handler for SIGINT (Ctrl+C)
|
||||
signal.signal(signal.SIGINT, self.signal_handler)
|
||||
|
||||
# Start the stream
|
||||
self.stream.start_stream()
|
||||
|
||||
def __exit__(self):
|
||||
self.stream.stop_stream()
|
||||
self.stream.close()
|
||||
self.p.terminate()
|
||||
|
||||
def signal_handler(self, sig, frame):
|
||||
print("\nYou pressed Ctrl+C! Press Enter")
|
||||
self.__exit__()
|
||||
|
||||
def callback(self, line):
|
||||
if 'mV' not in line:
|
||||
return
|
||||
v = int(line.split(' ')[1])
|
||||
if v == 0:
|
||||
return
|
||||
self.min_v = min(self.min_v, v)
|
||||
self.max_v = max(self.max_v, v)
|
||||
|
||||
# Recalculate the audio frequency to generate
|
||||
out_freq = (max_freq - min_freq) * (max_v - v) / (max_v - min_v) \
|
||||
+ min_freq
|
||||
global frequency
|
||||
frequency = linear_to_exponential_freq(v, self.min_v, self.max_v, min_freq, max_freq)
|
||||
|
||||
# Generate the samples and write them to the soundcard
|
||||
sinevs = out_freq / sampling_freq * numpy.pi * 2
|
||||
sample_buf[i] = sinev
|
||||
sinev += sinevs
|
||||
sinev = sinev if sinev < numpy.pi * 2 else sinev - numpy.pi * 2
|
||||
i = (i + 1) % sample_buf_size
|
||||
if not i:
|
||||
stream.write((numpy.sin(sample_buf) * volume).
|
||||
astype(numpy.float32).tobytes())
|
||||
# frequency = max_freq - ((max_freq - min_freq) * (v - self.min_v) / (self.max_v - self.min_v) + min_freq)
|
||||
#frequency = (frequency + new_frequency)/2
|
||||
|
||||
|
||||
def main():
|
||||
f = foo()
|
||||
run_pm3_cmd(f.callback)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -1065,10 +1065,10 @@
|
|||
},
|
||||
{
|
||||
"AID": "DD00DD",
|
||||
"Vendor": "Regional Transporation District (RTD) via masabi justride",
|
||||
"Vendor": "Regional Transporation District (RTD) via Masabi Ltd",
|
||||
"Country": "US",
|
||||
"Name": "MyRide Card (DEN)",
|
||||
"Description": "DEN MyRide Card",
|
||||
"Description": "DEN MyRide Card; Masabi Justride Tap and Ride DESFire Smartcard",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -4152,6 +4152,7 @@ static int CmdHFiClassLegRecLookUp(const char *Cmd) {
|
|||
}
|
||||
if (check_values) {
|
||||
PrintAndLogEx(SUCCESS, _GREEN_("CONFIRMED VALID RAW key ") _RED_("%s"), sprint_hex(div_key, 8));
|
||||
PrintAndLogEx(INFO, "You can now run -> "_YELLOW_("hf iclass unhash -k %s")" <-to find the pre-images.", sprint_hex(div_key, 8));
|
||||
verified = true;
|
||||
} else {
|
||||
PrintAndLogEx(INFO, _YELLOW_("Raw Key Invalid"));
|
||||
|
|
|
@ -7202,7 +7202,8 @@ static int CmdHf14AGen3Block(const char *Cmd) {
|
|||
" - You can specify part of manufacturer block as\n"
|
||||
" 4/7-bytes for UID change only\n"
|
||||
"\n"
|
||||
"NOTE: BCC, SAK, ATQA will be calculated automatically"
|
||||
"NOTE: BCC and ATQA will be calculated automatically\n"
|
||||
"SAK will be automatically set to default values if not specified"
|
||||
,
|
||||
"hf mf gen3blk --> print current data\n"
|
||||
"hf mf gen3blk -d 01020304 --> set 4 byte uid\n"
|
||||
|
|
|
@ -1540,21 +1540,13 @@ static int ulev1_print_version(uint8_t *data) {
|
|||
}
|
||||
|
||||
static int ntag_print_counter(void) {
|
||||
// NTAG has one counter/tearing. At address 0x02.
|
||||
// NTAG has one counter. At address 0x02. With no tearing.
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Counter"));
|
||||
uint8_t tear[1] = {0};
|
||||
uint8_t counter[3] = {0, 0, 0};
|
||||
uint16_t len;
|
||||
len = ulev1_readTearing(0x02, tear, sizeof(tear));
|
||||
(void)len;
|
||||
len = ulev1_readCounter(0x02, counter, sizeof(counter));
|
||||
(void)len;
|
||||
PrintAndLogEx(INFO, " [02]: %s", sprint_hex(counter, 3));
|
||||
PrintAndLogEx(SUCCESS, " - %02X tearing ( %s )"
|
||||
, tear[0]
|
||||
, (tear[0] == 0xBD) ? _GREEN_("ok") : _RED_("fail")
|
||||
);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -5833,6 +5825,127 @@ out:
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF14AMfUIncr(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfu incr",
|
||||
"Increment a MIFARE Ultralight Ev1 counter\n"
|
||||
"Will read but not increment counter if NTAG is detected",
|
||||
"hf mfu incr -c 0 -v 1337\n"
|
||||
"hf mfu incr -c 2 -v 0 -p FFFFFFFF");
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int1("c", "cnt", "<dec>", "Counter index from 0"),
|
||||
arg_int1("v", "val", "<dec>", "Value to increment by (0-16777215)"),
|
||||
arg_str0("p", "pwd", "<hex>", "PWD to authenticate with"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
uint8_t counter = arg_get_int_def(ctx, 1, 3);
|
||||
uint32_t value = arg_get_u32_def(ctx, 2, 16777216);
|
||||
|
||||
int pwd_len;
|
||||
uint8_t pwd[4] = { 0x00 };
|
||||
CLIGetHexWithReturn(ctx, 3, pwd, &pwd_len);
|
||||
bool has_key = false;
|
||||
if (pwd_len) {
|
||||
has_key = true;
|
||||
if (pwd_len != 4) {
|
||||
PrintAndLogEx(WARNING, "incorrect PWD length");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
}
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (counter > 2) {
|
||||
PrintAndLogEx(WARNING, "Counter index must be in range 0-2");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (value > 16777215) {
|
||||
PrintAndLogEx(WARNING, "Value to increment must be in range 0-16777215");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t increment_cmd[6] = { MIFARE_ULEV1_INCR_CNT, counter, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
increment_cmd[i + 2] = (value >> (8 * i)) & 0xff;
|
||||
}
|
||||
|
||||
iso14a_card_select_t card;
|
||||
if (ul_select(&card) == false) {
|
||||
PrintAndLogEx(FAILED, "failed to select card, exiting...");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint64_t tagtype = GetHF14AMfU_Type();
|
||||
uint64_t tags_with_counter_ul = MFU_TT_UL_EV1_48 | MFU_TT_UL_EV1_128 | MFU_TT_UL_EV1;
|
||||
uint64_t tags_with_counter_ntag = MFU_TT_NTAG_213 | MFU_TT_NTAG_213_F | MFU_TT_NTAG_213_C | MFU_TT_NTAG_213_TT | MFU_TT_NTAG_215 | MFU_TT_NTAG_216;
|
||||
if ((tagtype & (tags_with_counter_ul | tags_with_counter_ntag)) == 0) {
|
||||
PrintAndLogEx(WARNING, "tag type does not have counters");
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
bool is_ntag = (tagtype & tags_with_counter_ntag) != 0;
|
||||
if (is_ntag && (counter != 2)) {
|
||||
PrintAndLogEx(WARNING, "NTAG only has one counter at index 2");
|
||||
DropField();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t pack[4] = { 0, 0, 0, 0 };
|
||||
if (has_key) {
|
||||
if (ulev1_requestAuthentication(pwd, pack, sizeof(pack)) == PM3_EWRONGANSWER) {
|
||||
PrintAndLogEx(FAILED, "authentication failed UL-EV1/NTAG");
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t current_counter[3] = { 0, 0, 0 };
|
||||
int len = ulev1_readCounter(counter, current_counter, sizeof(current_counter));
|
||||
if (len != sizeof(current_counter)) {
|
||||
PrintAndLogEx(FAILED, "failed to read old counter");
|
||||
if (is_ntag) {
|
||||
PrintAndLogEx(HINT, "NTAG detected, try reading with PWD");
|
||||
}
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint32_t current_counter_num = current_counter[0] | (current_counter[1] << 8) | (current_counter[2] << 16);
|
||||
PrintAndLogEx(INFO, "Current counter... " _GREEN_("%8d") " - " _GREEN_("%s"), current_counter_num, sprint_hex(current_counter, 3));
|
||||
|
||||
if ((tagtype & tags_with_counter_ntag) != 0) {
|
||||
PrintAndLogEx(WARNING, "NTAG detected, unable to manually increment counter");
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint8_t resp[1] = { 0x00 };
|
||||
if (ul_send_cmd_raw(increment_cmd, sizeof(increment_cmd), resp, sizeof(resp)) < 0) {
|
||||
PrintAndLogEx(FAILED, "failed to increment counter");
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint8_t new_counter[3] = { 0, 0, 0 };
|
||||
int new_len = ulev1_readCounter(counter, new_counter, sizeof(new_counter));
|
||||
if (new_len != sizeof(current_counter)) {
|
||||
PrintAndLogEx(FAILED, "failed to read new counter");
|
||||
DropField();
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint32_t new_counter_num = new_counter[0] | (new_counter[1] << 8) | (new_counter[2] << 16);
|
||||
PrintAndLogEx(INFO, "New counter....... " _GREEN_("%8d") " - " _GREEN_("%s"), new_counter_num, sprint_hex(new_counter, 3));
|
||||
|
||||
DropField();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"list", CmdHF14AMfuList, AlwaysAvailable, "List MIFARE Ultralight / NTAG history"},
|
||||
|
@ -5845,6 +5958,7 @@ static command_t CommandTable[] = {
|
|||
{"cauth", CmdHF14AMfUCAuth, IfPm3Iso14443a, "Ultralight-C - Authentication"},
|
||||
{"setpwd", CmdHF14AMfUCSetPwd, IfPm3Iso14443a, "Ultralight-C - Set 3DES key"},
|
||||
{"dump", CmdHF14AMfUDump, IfPm3Iso14443a, "Dump MIFARE Ultralight family tag to binary file"},
|
||||
{"incr", CmdHF14AMfUIncr, IfPm3Iso14443a, "Increments Ev1/NTAG counter"},
|
||||
{"info", CmdHF14AMfUInfo, IfPm3Iso14443a, "Tag information"},
|
||||
{"ndefread", CmdHF14MfuNDEFRead, IfPm3Iso14443a, "Prints NDEF records from card"},
|
||||
{"rdbl", CmdHF14AMfURdBl, IfPm3Iso14443a, "Read block"},
|
||||
|
|
|
@ -444,6 +444,96 @@ static int CmdLFHitagSRead(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagSDump(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hitag hts dump",
|
||||
"Read all Hitag S memory and save to file\n"
|
||||
" Crypto mode: \n"
|
||||
" - key format ISK high + ISK low\n"
|
||||
" - default key 4F4E4D494B52 (ONMIKR)\n\n"
|
||||
" 8268/8310 password mode: \n"
|
||||
" - default password BBDD3399\n",
|
||||
"lf hitag hts dump --82xx -k BBDD3399 -> pwd mode\n"
|
||||
"lf hitag hts dump --crypto -> use def crypto\n"
|
||||
"lf hitag hts dump -k 4F4E4D494B52 -> crypto mode\n"
|
||||
"lf hitag hts dump --nrar 0102030411223344\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("8", "82xx", "8268/8310 mode"),
|
||||
arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
|
||||
arg_lit0(NULL, "crypto", "crypto mode"),
|
||||
arg_str0("k", "key", "<hex>", "pwd or key, 4 or 6 hex bytes"),
|
||||
arg_int0("m", "mode", "<dec>", "response protocol mode. 0 (Standard 00110), 1 (Advanced 11000), 2 (Advanced 11001), 3 (Fast Advanced 11010) (def: 3)"),
|
||||
arg_str0("f", "file", "<fn>", "specify file name"),
|
||||
arg_lit0(NULL, "ns", "no save to file"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
lf_hitag_data_t packet;
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
|
||||
if (process_hitags_common_args(ctx, &packet) < 0) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
|
||||
bool nosave = arg_get_lit(ctx, 7);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// read all pages
|
||||
packet.page = 0;
|
||||
packet.page_count = 0;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_HITAGS_READ, (uint8_t *) &packet, sizeof(packet));
|
||||
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_LF_HITAGS_READ, &resp, 5000) == false) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
print_error(resp.reason);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
lf_hts_read_response_t *card = (lf_hts_read_response_t *)resp.data.asBytes;
|
||||
|
||||
const int hts_mem_sizes[] = {1, 8, 64, 64};
|
||||
int mem_size = hts_mem_sizes[card->config_page.s.MEMT] * HITAGS_PAGE_SIZE;
|
||||
|
||||
hitags_config_t config = card->config_page.s;
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||
hitags_config_print(config);
|
||||
|
||||
if (nosave) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "Called with no save option");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
if (fnlen < 1) {
|
||||
char *fptr = filename;
|
||||
fptr += snprintf(filename, sizeof(filename), "lf-hitags-");
|
||||
FillFileNameByUID(fptr, card->pages[HITAGS_UID_PADR], "-dump", HITAGS_PAGE_SIZE);
|
||||
}
|
||||
|
||||
pm3_save_dump(filename, (uint8_t *)card->pages, mem_size, jsfHitag);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagSWrite(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hitag hts wrbl",
|
||||
|
@ -615,6 +705,7 @@ static command_t CommandTable[] = {
|
|||
{"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("General") " ------------------------"},
|
||||
{"reader", CmdLFHitagSReader, IfPm3Hitag, "Act like a Hitag S reader"},
|
||||
{"rdbl", CmdLFHitagSRead, IfPm3Hitag, "Read Hitag S page"},
|
||||
{"dump", CmdLFHitagSDump, IfPm3Hitag, "Dump Hitag S pages to a file"},
|
||||
{"wrbl", CmdLFHitagSWrite, IfPm3Hitag, "Write Hitag S page"},
|
||||
{"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("Simulation") " -----------------------"},
|
||||
{"sim", CmdLFHitagSSim, IfPm3Hitag, "Simulate Hitag S transponder"},
|
||||
|
|
|
@ -696,14 +696,18 @@ void print_progress(uint64_t count, uint64_t max, barMode_t style) {
|
|||
max = (count > max) ? count : max;
|
||||
#if defined(HAVE_READLINE)
|
||||
static int prev_cols = 0;
|
||||
int rows;
|
||||
rl_reset_screen_size(); // refresh Readline idea of the actual screen width
|
||||
rl_get_screen_size(&rows, &cols);
|
||||
int tmp_cols;
|
||||
rl_get_screen_size(NULL, &tmp_cols);
|
||||
// if cols==0: impossible to get screen size, e.g. when scripted
|
||||
if (tmp_cols != 0) {
|
||||
// don't call it if cols==0, it would segfault
|
||||
rl_reset_screen_size(); // refresh Readline idea of the actual screen width
|
||||
rl_get_screen_size(NULL, &cols);
|
||||
|
||||
if (cols < 36)
|
||||
return;
|
||||
if (cols < 36)
|
||||
return;
|
||||
}
|
||||
|
||||
(void) rows;
|
||||
if (prev_cols > cols) {
|
||||
PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ "");
|
||||
}
|
||||
|
|
45
fpga/xc2s50-5-tq144.ucf
Normal file
45
fpga/xc2s50-5-tq144.ucf
Normal file
|
@ -0,0 +1,45 @@
|
|||
# See the schematic for the pin assignment.
|
||||
|
||||
NET "adc_d<0>" LOC = "P54" ;
|
||||
NET "adc_d<1>" LOC = "P57" ;
|
||||
NET "adc_d<2>" LOC = "P59" ;
|
||||
NET "adc_d<3>" LOC = "P60" ;
|
||||
NET "adc_d<4>" LOC = "P62" ;
|
||||
NET "adc_d<5>" LOC = "P63" ;
|
||||
NET "adc_d<6>" LOC = "P65" ;
|
||||
NET "adc_d<7>" LOC = "P67" ;
|
||||
#NET "cross_hi" LOC = "P88" ;
|
||||
#NET "miso" LOC = "P40" ;
|
||||
NET "adc_clk" LOC = "P75" ;
|
||||
NET "adc_noe" LOC = "P74" ;
|
||||
NET "ck_1356meg" LOC = "P15" ;
|
||||
NET "ck_1356megb" LOC = "P12" ;
|
||||
NET "cross_lo" LOC = "P19" ;
|
||||
NET "dbg" LOC = "P112" ;
|
||||
NET "mosi" LOC = "P80" ;
|
||||
NET "ncs" LOC = "P79" ;
|
||||
NET "pck0" LOC = "P91" ;
|
||||
NET "pwr_hi" LOC = "P31" ;
|
||||
NET "pwr_lo" LOC = "P30" ;
|
||||
NET "pwr_oe1" LOC = "P28" ;
|
||||
NET "pwr_oe2" LOC = "P27" ;
|
||||
NET "pwr_oe3" LOC = "P26" ;
|
||||
NET "pwr_oe4" LOC = "P21" ;
|
||||
NET "spck" LOC = "P88" ;
|
||||
NET "ssp_clk" LOC = "P43" ;
|
||||
NET "ssp_din" LOC = "P99" ;
|
||||
NET "ssp_dout" LOC = "P94" ;
|
||||
NET "ssp_frame" LOC = "P100" ;
|
||||
|
||||
# definition of Clock nets:
|
||||
NET "ck_1356meg" TNM_NET = "clk_net_1356" ;
|
||||
NET "ck_1356megb" TNM_NET = "clk_net_1356b";
|
||||
NET "pck0" TNM_NET = "clk_net_pck0" ;
|
||||
NET "spck" TNM_NET = "clk_net_spck" ;
|
||||
|
||||
# Timing specs of clock nets:
|
||||
TIMEGRP "clk_net_1356_all" = "clk_net_1356" "clk_net_1356b" ;
|
||||
TIMESPEC "TS_1356MHz" = PERIOD "clk_net_1356_all" 74 ns HIGH 37 ns ;
|
||||
TIMESPEC "TS_24MHz" = PERIOD "clk_net_pck0" 42 ns HIGH 21 ns ;
|
||||
TIMESPEC "TS_4MHz" = PERIOD "clk_net_spck" 250 ns HIGH 125 ns ;
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue