Fix hf mfu dump command not running without file.

This commit is contained in:
turbocool3r
2024-07-09 21:03:57 +03:00
parent 09310dcacb
commit a52bb989e9
+96 -90
View File
@@ -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')