From b78b7a5d9babca813dea3673840260f2cb7f3407 Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Fri, 7 Feb 2025 16:33:16 -0600 Subject: [PATCH 1/3] Switch virtual and physical addresses to lists to support dumping multiple files at once #1319 --- .../framework/plugins/windows/dumpfiles.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/volatility3/framework/plugins/windows/dumpfiles.py b/volatility3/framework/plugins/windows/dumpfiles.py index 64d9be4db5..b10c519e7f 100755 --- a/volatility3/framework/plugins/windows/dumpfiles.py +++ b/volatility3/framework/plugins/windows/dumpfiles.py @@ -44,13 +44,15 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface] description="Process ID to include (all other processes are excluded)", optional=True, ), - requirements.IntRequirement( + requirements.ListRequirement( name="virtaddr", + element_type=int, description="Dump a single _FILE_OBJECT at this virtual address", optional=True, ), - requirements.IntRequirement( + requirements.ListRequirement( name="physaddr", + element_type=int, description="Dump a single _FILE_OBJECT at this physical address", optional=True, ), @@ -318,6 +320,7 @@ def _generator(self, procs: List, offsets: List): ) elif offsets: + # Now process any offsets explicitly requested by the user. for offset, is_virtual in offsets: try: @@ -355,10 +358,14 @@ def run(self): ): raise ValueError("Cannot use filter flag with an address flag") - if self.config.get("virtaddr", None) is not None: - offsets.append((self.config["virtaddr"], True)) - elif self.config.get("physaddr", None) is not None: - offsets.append((self.config["physaddr"], False)) + if self.config.get("virtaddr"): + for virtaddr in self.config["virtaddr"]: + offsets.append((virtaddr, True)) + + elif self.config.get("physaddr"): + for physaddr in self.config["physaddr"]: + offsets.append((physaddr, False)) + else: filter_func = pslist.PsList.create_pid_filter( [self.config.get("pid", None)] From 6babe158f0ad9d02a6221694babe457c426d8016 Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Sat, 15 Feb 2025 00:35:31 +0000 Subject: [PATCH 2/3] Address feedback --- .../framework/plugins/windows/dumpfiles.py | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/volatility3/framework/plugins/windows/dumpfiles.py b/volatility3/framework/plugins/windows/dumpfiles.py index b10c519e7f..9ce9e3141d 100755 --- a/volatility3/framework/plugins/windows/dumpfiles.py +++ b/volatility3/framework/plugins/windows/dumpfiles.py @@ -47,13 +47,13 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface] requirements.ListRequirement( name="virtaddr", element_type=int, - description="Dump a single _FILE_OBJECT at this virtual address", + description="Dump the _FILE_OBJECTs at the given virtual address(es)", optional=True, ), requirements.ListRequirement( name="physaddr", element_type=int, - description="Dump a single _FILE_OBJECT at this physical address", + description="Dump a single _FILE_OBJECTs at the given physical address(es)", optional=True, ), requirements.StringRequirement( @@ -320,25 +320,24 @@ def _generator(self, procs: List, offsets: List): ) elif offsets: + virtual_layer_name = kernel.layer_name - # Now process any offsets explicitly requested by the user. + #FIXME - change this after standard access to physical layer + physical_layer_name = self.context.layers[virtual_layer_name].config[ + "memory_layer" + ] + + # Now process any offsets explicitly requested by the user. for offset, is_virtual in offsets: try: - layer_name = kernel.layer_name - # switch to a memory layer if the user provided --physaddr instead of --virtaddr - if not is_virtual: - layer_name = self.context.layers[layer_name].config[ - "memory_layer" - ] - file_obj = self.context.object( kernel.symbol_table_name + constants.BANG + "_FILE_OBJECT", - layer_name=layer_name, - native_layer_name=kernel.layer_name, + layer_name=virtual_layer_name if is_virtual else physical_layer_name, + native_layer_name=virtual_layer_name, offset=offset, ) for result in self.process_file_object( - self.context, kernel.layer_name, self.open, file_obj + self.context, virtual_layer_name, self.open, file_obj ): yield (0, result) except exceptions.InvalidAddressException: @@ -362,11 +361,11 @@ def run(self): for virtaddr in self.config["virtaddr"]: offsets.append((virtaddr, True)) - elif self.config.get("physaddr"): + if self.config.get("physaddr"): for physaddr in self.config["physaddr"]: offsets.append((physaddr, False)) - else: + if not offsets: filter_func = pslist.PsList.create_pid_filter( [self.config.get("pid", None)] ) From 49b40eb30a31618630ac9106b171a4771f3594d7 Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Sat, 15 Feb 2025 00:36:12 +0000 Subject: [PATCH 3/3] Make black happy --- volatility3/framework/plugins/windows/dumpfiles.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/volatility3/framework/plugins/windows/dumpfiles.py b/volatility3/framework/plugins/windows/dumpfiles.py index 9ce9e3141d..42f2458007 100755 --- a/volatility3/framework/plugins/windows/dumpfiles.py +++ b/volatility3/framework/plugins/windows/dumpfiles.py @@ -322,17 +322,19 @@ def _generator(self, procs: List, offsets: List): elif offsets: virtual_layer_name = kernel.layer_name - #FIXME - change this after standard access to physical layer + # FIXME - change this after standard access to physical layer physical_layer_name = self.context.layers[virtual_layer_name].config[ "memory_layer" ] - # Now process any offsets explicitly requested by the user. + # Now process any offsets explicitly requested by the user. for offset, is_virtual in offsets: try: file_obj = self.context.object( kernel.symbol_table_name + constants.BANG + "_FILE_OBJECT", - layer_name=virtual_layer_name if is_virtual else physical_layer_name, + layer_name=( + virtual_layer_name if is_virtual else physical_layer_name + ), native_layer_name=virtual_layer_name, offset=offset, )