mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Merge branch 'main' into fix-senested-key-recovery
This commit is contained in:
@@ -494,6 +494,25 @@ class LFHIDIdReadArgsUnit(DeviceRequiredUnit):
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
raise NotImplementedError()
|
||||
|
||||
class LFVikingIdArgsUnit(DeviceRequiredUnit):
|
||||
@staticmethod
|
||||
def add_card_arg(parser: ArgumentParserNoExit, required=False):
|
||||
parser.add_argument("--id", type=str, required=required, help="Viking tag id", metavar="<hex>")
|
||||
return parser
|
||||
|
||||
def before_exec(self, args: argparse.Namespace):
|
||||
if not super().before_exec(args):
|
||||
return False
|
||||
if args.id is None or not re.match(r"^[a-fA-F0-9]{8}$", args.id):
|
||||
raise ArgsParserError("ID must include 8 HEX symbols")
|
||||
return True
|
||||
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
raise NotImplementedError("Please implement this")
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
raise NotImplementedError("Please implement this")
|
||||
|
||||
class TagTypeArgsUnit(DeviceRequiredUnit):
|
||||
@staticmethod
|
||||
def add_type_args(parser: ArgumentParserNoExit):
|
||||
@@ -525,7 +544,7 @@ lf_em = lf.subgroup('em', 'EM commands')
|
||||
lf_em_410x = lf_em.subgroup('410x', 'EM410x commands')
|
||||
lf_hid = lf.subgroup('hid', 'HID commands')
|
||||
lf_hid_prox = lf_hid.subgroup('prox', 'HID Prox commands')
|
||||
|
||||
lf_viking = lf.subgroup('viking', 'Viking commands')
|
||||
|
||||
@root.command('clear')
|
||||
class RootClear(BaseCLIUnit):
|
||||
@@ -3206,6 +3225,30 @@ class LFHIDProxEconfig(SlotIndexArgsAndGoUnit, LFHIDIdArgsUnit):
|
||||
print(f" OEM: {CG}{oem}{C0}")
|
||||
print(f" CN: {CG}{cn}{C0}")
|
||||
|
||||
@lf_viking.command('read')
|
||||
class LFVikingRead(ReaderRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
parser = ArgumentParserNoExit()
|
||||
parser.description = 'Scan Viking tag and print id'
|
||||
return parser
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
id = self.cmd.viking_scan()
|
||||
print(f"Viking: {CG}{id.hex()}{C0}")
|
||||
|
||||
|
||||
@lf_viking.command('write')
|
||||
class LFVikingWriteT55xx(LFVikingIdArgsUnit, ReaderRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
parser = ArgumentParserNoExit()
|
||||
parser.description = 'Write Viking id to t55xx'
|
||||
return self.add_card_arg(parser, required=True)
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
id_hex = args.id
|
||||
id_bytes = bytes.fromhex(id_hex)
|
||||
self.cmd.viking_write_to_t55xx(id_bytes)
|
||||
print(f" - Viking ID(8H): {id_hex} write done.")
|
||||
|
||||
@hw_slot.command('list')
|
||||
class HWSlotList(DeviceRequiredUnit):
|
||||
@@ -3327,6 +3370,9 @@ class HWSlotList(DeviceRequiredUnit):
|
||||
if oem > 0:
|
||||
print(f' {"OEM:":40}{CY}{oem}{C0}')
|
||||
print(f' {"CN:":40}{CY}{cn}{C0}')
|
||||
if lf_tag_type == TagSpecificType.Viking:
|
||||
id = self.cmd.viking_get_emu_id()
|
||||
print(f' {"ID:":40}{CY}{id.hex().upper()}{C0}')
|
||||
if current != selected:
|
||||
self.cmd.set_active_slot(selected)
|
||||
|
||||
@@ -3463,6 +3509,28 @@ class LFEM410xEconfig(SlotIndexArgsAndGoUnit, LFEMIdArgsUnit):
|
||||
print(' - Get em410x tag id success.')
|
||||
print(f'ID: {response.hex()}')
|
||||
|
||||
@lf_viking.command('econfig')
|
||||
class LFVikingEconfig(SlotIndexArgsAndGoUnit, LFVikingIdArgsUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
parser = ArgumentParserNoExit()
|
||||
parser.description = 'Set emulated Viking card id'
|
||||
self.add_slot_args(parser)
|
||||
self.add_card_arg(parser)
|
||||
return parser
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
if args.id is not None:
|
||||
slotinfo = self.cmd.get_slot_info()
|
||||
selected = SlotNumber.from_fw(self.cmd.get_active_slot())
|
||||
lf_tag_type = TagSpecificType(slotinfo[selected - 1]['lf'])
|
||||
if lf_tag_type != TagSpecificType.Viking:
|
||||
print(f"{CR}WARNING{C0}: Slot type not set to Viking.")
|
||||
self.cmd.viking_set_emu_id(bytes.fromhex(args.id))
|
||||
print(' - Set Viking tag id success.')
|
||||
else:
|
||||
response = self.cmd.viking_get_emu_id()
|
||||
print(' - Get Viking tag id success.')
|
||||
print(f'ID: {response.hex().upper()}')
|
||||
|
||||
@hw_slot.command('nick')
|
||||
class HWSlotNick(SlotIndexArgsUnit, SenseTypeArgsUnit):
|
||||
|
||||
@@ -475,6 +475,31 @@ class ChameleonCMD:
|
||||
data = struct.pack(f'!13s4s{4*len(old_keys)}s', id_bytes, new_key, b''.join(old_keys))
|
||||
return self.device.send_cmd_sync(Command.HIDPROX_WRITE_TO_T55XX, data)
|
||||
|
||||
@expect_response(Status.LF_TAG_OK)
|
||||
def viking_scan(self):
|
||||
"""
|
||||
Read the card number of Viking.
|
||||
|
||||
:return:
|
||||
"""
|
||||
resp = self.device.send_cmd_sync(Command.VIKING_SCAN)
|
||||
if resp.status == Status.LF_TAG_OK:
|
||||
resp.parsed = resp.data # uid
|
||||
return resp
|
||||
|
||||
@expect_response(Status.LF_TAG_OK)
|
||||
def viking_write_to_t55xx(self, id_bytes: bytes):
|
||||
"""
|
||||
Write Viking card number into T55XX.
|
||||
|
||||
:param id_bytes: ID card number
|
||||
:return:
|
||||
"""
|
||||
if len(id_bytes) != 4:
|
||||
raise ValueError("The id bytes length must equal 4")
|
||||
data = struct.pack(f'!4s4s{4*len(old_keys)}s', id_bytes, new_key, b''.join(old_keys))
|
||||
return self.device.send_cmd_sync(Command.VIKING_WRITE_TO_T55XX, data)
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def get_slot_info(self):
|
||||
"""
|
||||
@@ -610,6 +635,28 @@ class ChameleonCMD:
|
||||
resp.parsed = struct.unpack('>BIBIBH', resp.data[:13])
|
||||
return resp
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def viking_set_emu_id(self, id: bytes):
|
||||
"""
|
||||
Set the card number emulated by Viking.
|
||||
|
||||
:param id_bytes: byte of the card number
|
||||
:return:
|
||||
"""
|
||||
if len(id) != 4:
|
||||
raise ValueError("The id bytes length must equal 4")
|
||||
data = struct.pack('4s', id)
|
||||
return self.device.send_cmd_sync(Command.VIKING_SET_EMU_ID, data)
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def viking_get_emu_id(self):
|
||||
"""
|
||||
Get the emulated Viking card id
|
||||
"""
|
||||
resp = self.device.send_cmd_sync(Command.VIKING_GET_EMU_ID)
|
||||
resp.parsed = resp.data
|
||||
return resp
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def mf1_set_detection_enable(self, enabled: bool):
|
||||
"""
|
||||
|
||||
@@ -78,6 +78,8 @@ class Command(enum.IntEnum):
|
||||
EM410X_WRITE_TO_T55XX = 3001
|
||||
HIDPROX_SCAN = 3002
|
||||
HIDPROX_WRITE_TO_T55XX = 3003
|
||||
VIKING_SCAN = 3004
|
||||
VIKING_WRITE_TO_T55XX = 3005
|
||||
|
||||
MF1_WRITE_EMU_BLOCK_DATA = 4000
|
||||
HF14A_SET_ANTI_COLL_DATA = 4001
|
||||
@@ -126,6 +128,8 @@ class Command(enum.IntEnum):
|
||||
EM410X_GET_EMU_ID = 5001
|
||||
HIDPROX_SET_EMU_ID = 5002
|
||||
HIDPROX_GET_EMU_ID = 5003
|
||||
VIKING_SET_EMU_ID = 5004
|
||||
VIKING_GET_EMU_ID = 5005
|
||||
|
||||
|
||||
@enum.unique
|
||||
@@ -260,7 +264,7 @@ class TagSpecificType(enum.IntEnum):
|
||||
# PAC/Stanley
|
||||
# Presco
|
||||
# Visa2000
|
||||
# Viking
|
||||
Viking = 170
|
||||
# Noralsy
|
||||
# Jablotron
|
||||
|
||||
@@ -347,6 +351,8 @@ class TagSpecificType(enum.IntEnum):
|
||||
return "EM410X/64"
|
||||
elif self == TagSpecificType.HIDProx:
|
||||
return "HIDProx"
|
||||
elif self == TagSpecificType.Viking:
|
||||
return "Viking"
|
||||
elif self == TagSpecificType.MIFARE_Mini:
|
||||
return "Mifare Mini"
|
||||
elif self == TagSpecificType.MIFARE_1024:
|
||||
|
||||
Reference in New Issue
Block a user