mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Fix hf mfu dump command not running without file.
This commit is contained in:
@@ -2048,6 +2048,85 @@ class HFMFUDUMP(MFUAuthArgsUnit):
|
||||
parser.add_argument('-t', '--type', type=str, required=False, choices=['bin', 'hex'],
|
||||
help="Force writing as either raw binary or hex.")
|
||||
return parser
|
||||
|
||||
def do_dump(self, args: argparse.Namespace, param, fd, save_as_eml):
|
||||
if args.qty is not None:
|
||||
stop_page = min(args.page + args.qty, 256)
|
||||
else:
|
||||
stop_page = 256
|
||||
|
||||
options = {
|
||||
'activate_rf_field': 0,
|
||||
'wait_response': 1,
|
||||
'append_crc': 1,
|
||||
'auto_select': 1,
|
||||
'keep_rf_field': 1,
|
||||
'check_response_crc': 1,
|
||||
}
|
||||
|
||||
needs_stop = False
|
||||
|
||||
if param.key is not None:
|
||||
options['keep_rf_field'] = 1
|
||||
try:
|
||||
resp = self.cmd.hf14a_raw(options=options, resp_timeout_ms=200, data=struct.pack('!B', 0x1B)+param.key)
|
||||
|
||||
needs_stop = len(resp) < 2
|
||||
if not needs_stop:
|
||||
print(f" - PACK: {resp[:2].hex()}")
|
||||
except Exception as e:
|
||||
# failed auth may cause tags to be lost
|
||||
needs_stop = True
|
||||
|
||||
options['auto_select'] = 0
|
||||
|
||||
# this handles auth failure
|
||||
if needs_stop:
|
||||
print(f" {CR}- Auth failed{C0}")
|
||||
if fd is not None:
|
||||
fd.close()
|
||||
fd = None
|
||||
|
||||
for i in range(args.page, stop_page):
|
||||
# this could be done once in theory but the command would need to be optimized properly
|
||||
if param.key is not None and not needs_stop:
|
||||
resp = self.cmd.hf14a_raw(options=options, resp_timeout_ms=200, data=struct.pack('!B', 0x1B)+param.key)
|
||||
options['auto_select'] = 0 # prevent resets
|
||||
pack = resp[:2].hex()
|
||||
|
||||
# disable the rf field after the last command
|
||||
if i == (stop_page - 1) or needs_stop:
|
||||
options['keep_rf_field'] = 0
|
||||
|
||||
try:
|
||||
resp = self.cmd.hf14a_raw(options=options, resp_timeout_ms=200, data=struct.pack('!BB', 0x30, i))
|
||||
except:
|
||||
# probably lost tag, but we still need to disable rf field
|
||||
resp = None
|
||||
|
||||
if needs_stop:
|
||||
# break if this command was sent just to disable RF field
|
||||
break
|
||||
elif resp is None or len(resp) == 0:
|
||||
# we need to disable RF field if we reached the last valid page so send one more read command
|
||||
needs_stop = True
|
||||
continue
|
||||
|
||||
# after the read we are sure we no longer need to select again
|
||||
options['auto_select'] = 0
|
||||
|
||||
# TODO: can be optimized as we get 4 pages at once but beware of wrapping
|
||||
# in case of end of memory or LOCK on ULC and no key provided
|
||||
data = resp[:4]
|
||||
print(f" - Page {i:2}: {data.hex()}")
|
||||
if fd is not None:
|
||||
if save_as_eml:
|
||||
fd.write(data.hex()+'\n')
|
||||
else:
|
||||
fd.write(data)
|
||||
|
||||
if args.file != '':
|
||||
print(f" - {CG}Dump written in {args.file}.{C0}")
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
param = self.get_param(args)
|
||||
@@ -2056,98 +2135,25 @@ class HFMFUDUMP(MFUAuthArgsUnit):
|
||||
fd = None
|
||||
save_as_eml = False
|
||||
|
||||
if file_type is None:
|
||||
if args.file.endswith('.eml') or args.file.endswith('.txt'):
|
||||
file_type = 'hex'
|
||||
else:
|
||||
file_type = 'bin'
|
||||
if args.file != '':
|
||||
if file_type is None:
|
||||
if args.file.endswith('.eml') or args.file.endswith('.txt'):
|
||||
file_type = 'hex'
|
||||
else:
|
||||
file_type = 'bin'
|
||||
|
||||
if file_type == 'hex':
|
||||
fd = open(args.file, 'w+')
|
||||
save_as_eml = True
|
||||
if file_type == 'hex':
|
||||
fd = open(args.file, 'w+')
|
||||
save_as_eml = True
|
||||
else:
|
||||
fd = open(args.file, 'wb+')
|
||||
|
||||
if fd is not None:
|
||||
with fd:
|
||||
fd.truncate(0)
|
||||
self.do_dump(args, param, fd, save_as_eml)
|
||||
else:
|
||||
fd = open(args.file, 'wb+')
|
||||
|
||||
with fd:
|
||||
fd.truncate(0)
|
||||
|
||||
if args.qty is not None:
|
||||
stop_page = min(args.page + args.qty, 256)
|
||||
else:
|
||||
stop_page = 256
|
||||
|
||||
options = {
|
||||
'activate_rf_field': 0,
|
||||
'wait_response': 1,
|
||||
'append_crc': 1,
|
||||
'auto_select': 1,
|
||||
'keep_rf_field': 1,
|
||||
'check_response_crc': 1,
|
||||
}
|
||||
|
||||
needs_stop = False
|
||||
|
||||
if param.key is not None:
|
||||
options['keep_rf_field'] = 1
|
||||
try:
|
||||
resp = self.cmd.hf14a_raw(options=options, resp_timeout_ms=200, data=struct.pack('!B', 0x1B)+param.key)
|
||||
|
||||
needs_stop = len(resp) < 2
|
||||
if not needs_stop:
|
||||
print(f" - PACK: {resp[:2].hex()}")
|
||||
except Exception as e:
|
||||
# failed auth may cause tags to be lost
|
||||
needs_stop = True
|
||||
|
||||
options['auto_select'] = 0
|
||||
|
||||
# this handles auth failure
|
||||
if needs_stop:
|
||||
print(f" {CR}- Auth failed{C0}")
|
||||
if fd is not None:
|
||||
fd.close()
|
||||
fd = None
|
||||
|
||||
for i in range(args.page, stop_page):
|
||||
# this could be done once in theory but the command would need to be optimized properly
|
||||
if param.key is not None and not needs_stop:
|
||||
resp = self.cmd.hf14a_raw(options=options, resp_timeout_ms=200, data=struct.pack('!B', 0x1B)+param.key)
|
||||
options['auto_select'] = 0 # prevent resets
|
||||
pack = resp[:2].hex()
|
||||
|
||||
# disable the rf field after the last command
|
||||
if i == (stop_page - 1) or needs_stop:
|
||||
options['keep_rf_field'] = 0
|
||||
|
||||
try:
|
||||
resp = self.cmd.hf14a_raw(options=options, resp_timeout_ms=200, data=struct.pack('!BB', 0x30, i))
|
||||
except:
|
||||
# probably lost tag, but we still need to disable rf field
|
||||
resp = None
|
||||
|
||||
if needs_stop:
|
||||
# break if this command was sent just to disable RF field
|
||||
break
|
||||
elif resp is None or len(resp) == 0:
|
||||
# we need to disable RF field if we reached the last valid page so send one more read command
|
||||
needs_stop = True
|
||||
continue
|
||||
|
||||
# after the read we are sure we no longer need to select again
|
||||
options['auto_select'] = 0
|
||||
|
||||
# TODO: can be optimized as we get 4 pages at once but beware of wrapping
|
||||
# in case of end of memory or LOCK on ULC and no key provided
|
||||
data = resp[:4]
|
||||
print(f" - Page {i:2}: {data.hex()}")
|
||||
if fd is not None:
|
||||
if save_as_eml:
|
||||
fd.write(data.hex()+'\n')
|
||||
else:
|
||||
fd.write(data)
|
||||
|
||||
if args.file is not None:
|
||||
print(f" - {CG}Dump written in {args.file}.{C0}")
|
||||
self.do_dump(args, param, fd, save_as_eml)
|
||||
|
||||
|
||||
@hf_mfu.command('version')
|
||||
|
||||
Reference in New Issue
Block a user