2121 "vacb" : "SharedCacheMap" ,
2222}
2323
24+
2425class DumpFiles (interfaces .plugins .PluginInterface ):
2526 """Dumps cached file contents from Windows memory samples."""
2627
@@ -31,26 +32,25 @@ class DumpFiles(interfaces.plugins.PluginInterface):
3132 def get_requirements (cls ) -> List [interfaces .configuration .RequirementInterface ]:
3233 # Since we're calling the plugin, make sure we have the plugin's requirements
3334 return [
34- requirements .TranslationLayerRequirement (name = 'primary' ,
35- description = 'Memory layer for the kernel' ,
36- architectures = ["Intel32" , "Intel64" ]),
37- requirements .SymbolTableRequirement (name = "nt_symbols" , description = "Windows kernel symbols" ),
38- requirements .IntRequirement (name = 'pid' ,
39- description = "Process ID to include (all other processes are excluded)" ,
40- optional = True ),
41- requirements .IntRequirement (name = 'virtaddr' ,
42- description = "Dump a single _FILE_OBJECT at this virtual address" ,
43- optional = True ),
44- requirements .IntRequirement (name = 'physaddr' ,
45- description = "Dump a single _FILE_OBJECT at this physical address" ,
46- optional = True ),
47- requirements .VersionRequirement (name = 'pslist' , component = pslist .PsList , version = (2 , 0 , 0 )),
48- requirements .VersionRequirement (name = 'handles' , component = handles .Handles , version = (1 , 0 , 0 ))
35+ requirements .TranslationLayerRequirement (name = 'primary' ,
36+ description = 'Memory layer for the kernel' ,
37+ architectures = ["Intel32" , "Intel64" ]),
38+ requirements .SymbolTableRequirement (name = "nt_symbols" , description = "Windows kernel symbols" ),
39+ requirements .IntRequirement (name = 'pid' ,
40+ description = "Process ID to include (all other processes are excluded)" ,
41+ optional = True ),
42+ requirements .IntRequirement (name = 'virtaddr' ,
43+ description = "Dump a single _FILE_OBJECT at this virtual address" ,
44+ optional = True ),
45+ requirements .IntRequirement (name = 'physaddr' ,
46+ description = "Dump a single _FILE_OBJECT at this physical address" ,
47+ optional = True ),
48+ requirements .VersionRequirement (name = 'pslist' , component = pslist .PsList , version = (2 , 0 , 0 )),
49+ requirements .VersionRequirement (name = 'handles' , component = handles .Handles , version = (1 , 0 , 0 ))
4950 ]
5051
5152 @classmethod
52- def dump_file_producer (cls ,
53- file_object : interfaces .objects .ObjectInterface ,
53+ def dump_file_producer (cls , file_object : interfaces .objects .ObjectInterface ,
5454 memory_object : interfaces .objects .ObjectInterface ,
5555 open_method : Type [interfaces .plugins .FileHandlerInterface ],
5656 layer : interfaces .layers .DataLayerInterface ,
@@ -86,14 +86,11 @@ def dump_file_producer(cls,
8686 vollog .debug ("Stored {}" .format (filedata .preferred_filename ))
8787 return filedata
8888 except exceptions .InvalidAddressException :
89- vollog .debug ("Unable to dump file at {0:#x}" .format (
90- file_object .vol .offset ))
89+ vollog .debug ("Unable to dump file at {0:#x}" .format (file_object .vol .offset ))
9190 return None
9291
9392 @classmethod
94- def process_file_object (cls ,
95- context : interfaces .context .ContextInterface ,
96- primary_layer_name : str ,
93+ def process_file_object (cls , context : interfaces .context .ContextInterface , primary_layer_name : str ,
9794 open_method : Type [interfaces .plugins .FileHandlerInterface ],
9895 file_obj : interfaces .objects .ObjectInterface ) -> Tuple :
9996 """Given a FILE_OBJECT, dump data to separate files for each of the three file caches.
@@ -153,10 +150,8 @@ def process_file_object(cls,
153150 for memory_object , layer , extension in dump_parameters :
154151 cache_name = EXTENSION_CACHE_MAP [extension ]
155152 desired_file_name = "file.{0:#x}.{1:#x}.{2}.{3}.{4}" .format (file_obj .vol .offset ,
156- memory_object .vol .offset ,
157- cache_name ,
158- ntpath .basename (obj_name ),
159- extension )
153+ memory_object .vol .offset , cache_name ,
154+ ntpath .basename (obj_name ), extension )
160155
161156 file_handle = DumpFiles .dump_file_producer (file_obj , memory_object , open_method , layer , desired_file_name )
162157
@@ -165,8 +160,10 @@ def process_file_object(cls,
165160 file_handle .close ()
166161 file_output = file_handle .preferred_filename
167162
168- yield (cache_name , format_hints .Hex (file_obj .vol .offset ),
169- ntpath .basename (obj_name ), # temporary, so its easier to visualize output
163+ yield (
164+ cache_name ,
165+ format_hints .Hex (file_obj .vol .offset ),
166+ ntpath .basename (obj_name ), # temporary, so its easier to visualize output
170167 file_output )
171168
172169 def _generator (self , procs : List , offsets : List ):
@@ -176,13 +173,13 @@ def _generator(self, procs: List, offsets: List):
176173 # private variables, so we need an instance (for now, anyway). We _could_ call Handles._generator()
177174 # to do some of the other work that is duplicated here, but then we'd need to parse the TreeGrid
178175 # results instead of just dealing with them as direct objects here.
179- handles_plugin = handles .Handles (context = self .context , config_path = self ._config_path )
180- type_map = handles_plugin .get_type_map (context = self .context ,
181- layer_name = self .config ["primary" ],
182- symbol_table = self .config ["nt_symbols" ])
183- cookie = handles_plugin .find_cookie (context = self .context ,
184- layer_name = self .config ["primary" ],
185- symbol_table = self .config ["nt_symbols" ])
176+ handles_plugin = handles .Handles (context = self .context , config_path = self ._config_path )
177+ type_map = handles_plugin .get_type_map (context = self .context ,
178+ layer_name = self .config ["primary" ],
179+ symbol_table = self .config ["nt_symbols" ])
180+ cookie = handles_plugin .find_cookie (context = self .context ,
181+ layer_name = self .config ["primary" ],
182+ symbol_table = self .config ["nt_symbols" ])
186183
187184 for proc in procs :
188185
@@ -198,7 +195,8 @@ def _generator(self, procs: List, offsets: List):
198195 obj_type = entry .get_object_type (type_map , cookie )
199196 if obj_type == "File" :
200197 file_obj = entry .Body .cast ("_FILE_OBJECT" )
201- for result in self .process_file_object (self .context , self .config ["primary" ], self .open , file_obj ):
198+ for result in self .process_file_object (self .context , self .config ["primary" ], self .open ,
199+ file_obj ):
202200 yield (0 , result )
203201 except exceptions .InvalidAddressException :
204202 vollog .log (constants .LOGLEVEL_VVV ,
@@ -221,7 +219,8 @@ def _generator(self, procs: List, offsets: List):
221219 if not file_obj .is_valid ():
222220 continue
223221
224- for result in self .process_file_object (self .context , self .config ["primary" ], self .open , file_obj ):
222+ for result in self .process_file_object (self .context , self .config ["primary" ], self .open ,
223+ file_obj ):
225224 yield (0 , result )
226225 except exceptions .InvalidAddressException :
227226 vollog .log (constants .LOGLEVEL_VVV ,
@@ -237,14 +236,13 @@ def _generator(self, procs: List, offsets: List):
237236 layer_name = self .context .layers [layer_name ].config ["memory_layer" ]
238237
239238 file_obj = self .context .object (self .config ["nt_symbols" ] + constants .BANG + "_FILE_OBJECT" ,
240- layer_name = layer_name ,
241- native_layer_name = self .config ["primary" ],
242- offset = offset )
239+ layer_name = layer_name ,
240+ native_layer_name = self .config ["primary" ],
241+ offset = offset )
243242 for result in self .process_file_object (self .context , self .config ["primary" ], self .open , file_obj ):
244243 yield (0 , result )
245244 except exceptions .InvalidAddressException :
246- vollog .log (constants .LOGLEVEL_VVV ,
247- "Cannot extract file at {0:#x}" .format (offset ))
245+ vollog .log (constants .LOGLEVEL_VVV , "Cannot extract file at {0:#x}" .format (offset ))
248246
249247 def run (self ):
250248 # a list of tuples (<int>, <bool>) where <int> is the address and <bool> is True for virtual.
@@ -261,8 +259,7 @@ def run(self):
261259 procs = pslist .PsList .list_processes (self .context ,
262260 self .config ["primary" ],
263261 self .config ["nt_symbols" ],
264- filter_func = filter_func )
262+ filter_func = filter_func )
265263
266- return renderers .TreeGrid (
267- [("Cache" , str ), ("FileObject" , format_hints .Hex ), ("FileName" , str ), ("Result" , str )],
268- self ._generator (procs , offsets ))
264+ return renderers .TreeGrid ([("Cache" , str ), ("FileObject" , format_hints .Hex ), ("FileName" , str ),
265+ ("Result" , str )], self ._generator (procs , offsets ))
0 commit comments