diff --git a/src/gallia/commands/__init__.py b/src/gallia/commands/__init__.py index ce9c11fcc..da4cd4457 100644 --- a/src/gallia/commands/__init__.py +++ b/src/gallia/commands/__init__.py @@ -92,3 +92,10 @@ "SimpleTestXCP", "VirtualECU", ] + + +if sys.platform == "win32": + from gallia.commands.script.flexray import FRDump + + registry.append(FRDump) + __all__.append("FRDump") diff --git a/src/gallia/commands/script/flexray.py b/src/gallia/commands/script/flexray.py new file mode 100644 index 000000000..ffdc53f6f --- /dev/null +++ b/src/gallia/commands/script/flexray.py @@ -0,0 +1,62 @@ +# SPDX-FileCopyrightText: AISEC Pentesting Team +# +# SPDX-License-Identifier: Apache-2.0 + +import sys +from argparse import BooleanOptionalAction, Namespace + +assert sys.platform == "win32" + +from gallia.command import AsyncScript +from gallia.transports.flexray_vector import RawFlexRayTransport +from gallia.utils import auto_int + + +class FRDump(AsyncScript): + """Spawn a virtual ECU for testing purposes""" + + COMMAND = "fr-dump" + SHORT_HELP = "runs a helper tool that dumps flexray bus traffic to stdout" + + def configure_parser(self) -> None: + self.parser.add_argument( + "--src-slot", + type=auto_int, + help="the source flexray slot", + ) + self.parser.add_argument( + "--target-slot", + type=auto_int, + help="the target flexray slot", + ) + self.parser.add_argument( + "--filter-null-frames", + action=BooleanOptionalAction, + default=True, + help="filter mysterious null frames out", + ) + + async def main(self, args: Namespace) -> None: + tp = await RawFlexRayTransport.connect("fr-raw:", None) + + if args.src_slot or args.target_slot: + tp.add_block_all_filter() + + if args.src_slot is not None: + tp.set_acceptance_filter(args.src_slot) + + if args.target_slot is not None: + tp.set_acceptance_filter(args.target_slot) + + tp.activate_channel() + + while True: + frame = await tp.read_frame() + + if args.filter_null_frames is True: + # Best effort; in our use case this was the ISO-TP header. + # The first ISO-TP header byte is never 0x00. + if frame.data[0] == 0x00: + continue + + print(f" -> slot_id: {frame.slot_id}; data: {frame.data.hex()}")