def _generator(self, tasks): # determine if we're on a 32 or 64 bit kernel if self.context.symbol_space.get_type(self.config["vmlinux"] + constants.BANG + "pointer").size == 4: is_32bit_arch = True else: is_32bit_arch = False for task in tasks: process_name = utility.array_to_string(task.comm) for vma, data in self._list_injections(task): if is_32bit_arch: architecture = "intel" else: architecture = "intel64" disasm = interfaces.renderers.Disassembly( data, vma.vm_start, architecture) yield (0, (task.pid, process_name, format_hints.Hex(vma.vm_start), format_hints.Hex(vma.vm_end), vma.get_protection(), format_hints.HexBytes(data), disasm))
def _generator(self, procs): # determine if we're on a 32 or 64 bit kernel kernel = self.context.modules[self.config['kernel']] is_32bit_arch = not symbols.symbol_table_is_64bit( self.context, kernel.symbol_table_name) for proc in procs: process_name = utility.array_to_string(proc.ImageFileName) for vad, data in self.list_injections(self.context, kernel.layer_name, kernel.symbol_table_name, proc): # if we're on a 64 bit kernel, we may still need 32 bit disasm due to wow64 if is_32bit_arch or proc.get_is_wow64(): architecture = "intel" else: architecture = "intel64" disasm = interfaces.renderers.Disassembly( data, vad.get_start(), architecture) file_output = "Disabled" if self.config['dump']: file_output = "Error outputting to file" try: file_handle = vadinfo.VadInfo.vad_dump( self.context, proc, vad, self.open) file_handle.close() file_output = file_handle.preferred_filename except (exceptions.InvalidAddressException, OverflowError) as excp: vollog.debug( "Unable to dump PE with pid {0}.{1:#x}: {2}". format(proc.UniqueProcessId, vad.get_start(), excp)) yield (0, (proc.UniqueProcessId, process_name, format_hints.Hex(vad.get_start()), format_hints.Hex(vad.get_end()), vad.get_tag(), vad.get_protection( vadinfo.VadInfo.protect_values( self.context, kernel.layer_name, kernel.symbol_table_name), vadinfo.winnt_protections), vad.get_commit_charge(), vad.get_private_memory(), file_output, format_hints.HexBytes(data), disasm))
def _generator(self, tasks): # determine if we're on a 32 or 64 bit kernel if self.context.modules[self.config['kernel']].get_type( "pointer").size == 4: is_32bit_arch = True else: is_32bit_arch = False for task in tasks: process_name = utility.array_to_string(task.p_comm) for vma, data in self._list_injections(task): if is_32bit_arch: architecture = "intel" else: architecture = "intel64" disasm = interfaces.renderers.Disassembly( data, vma.links.start, architecture) yield (0, (task.p_pid, process_name, format_hints.Hex(vma.links.start), format_hints.Hex(vma.links.end), vma.get_perms(), format_hints.HexBytes(data), disasm))
def list_userassist( self, hive: RegistryHive) -> Generator[Tuple[int, Tuple], None, None]: """Generate userassist data for a registry hive.""" hive_name = hive.hive.cast(self.config["nt_symbols"] + constants.BANG + "_CMHIVE").get_name() if self._win7 is None: try: self._win7 = self._win7_or_later() except exceptions.SymbolError: # self._win7 will be None and only registry value rawdata will be output pass self._determine_userassist_type() userassist_node_path = hive.get_key( "software\\microsoft\\windows\\currentversion\\explorer\\userassist", return_list=True) if not userassist_node_path: vollog.warning( "list_userassist did not find a valid node_path (or None)") return if not isinstance(userassist_node_path, list): vollog.warning( "userassist_node_path did not return a list as expected") return userassist_node = userassist_node_path[-1] # iterate through the GUIDs under the userassist key for guidkey in userassist_node.get_subkeys(): # each guid key should have a Count key in it for countkey in guidkey.get_subkeys(): countkey_path = countkey.get_key_path() countkey_last_write_time = conversion.wintime_to_datetime( countkey.LastWriteTime.QuadPart) # output the parent Count key result = ( 0, (renderers.format_hints.Hex(hive.hive_offset), hive_name, countkey_path, countkey_last_write_time, "Key", renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue()) ) # type: Tuple[int, Tuple[format_hints.Hex, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any]] yield result # output any subkeys under Count for subkey in countkey.get_subkeys(): subkey_name = subkey.get_name() result = (1, ( renderers.format_hints.Hex(hive.hive_offset), hive_name, countkey_path, countkey_last_write_time, "Subkey", subkey_name, renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), )) yield result # output any values under Count for value in countkey.get_values(): value_name = value.get_name() try: value_name = codecs.encode(value_name, "rot_13") except UnicodeDecodeError: pass if self._win7: guid = value_name.split("\\")[0] if guid in self._folder_guids: value_name = value_name.replace( guid, self._folder_guids[guid]) userassist_data_dict = self.parse_userassist_data(value) result = (1, ( renderers.format_hints.Hex(hive.hive_offset), hive_name, countkey_path, countkey_last_write_time, "Value", value_name, userassist_data_dict["id"], userassist_data_dict["count"], userassist_data_dict["focus"], userassist_data_dict["time"], userassist_data_dict["lastupdated"], format_hints.HexBytes(userassist_data_dict["rawdata"]), )) yield result
def _generator(self) -> Iterator[Tuple]: kernel = self.context.modules[self.config['kernel']] physical_layer_name = self.context.layers[ kernel.layer_name].config.get('memory_layer', None) # Decide of Memory Dump Architecture layer = self.context.layers[physical_layer_name] architecture = "intel" if not symbols.symbol_table_is_64bit( self.context, kernel.symbol_table_name) else "intel64" # Read in the Symbol File symbol_table = intermed.IntermediateSymbolTable.create( context=self.context, config_path=self.config_path, sub_path="windows", filename="mbr", class_types={ 'PARTITION_TABLE': mbr.PARTITION_TABLE, 'PARTITION_ENTRY': mbr.PARTITION_ENTRY }) partition_table_object = symbol_table + constants.BANG + "PARTITION_TABLE" # Define Signature and Data Length mbr_signature = b"\x55\xAA" mbr_length = 0x200 bootcode_length = 0x1B8 # Scan the Layer for Raw Master Boot Record (MBR) and parse the fields for offset, _value in layer.scan( context=self.context, scanner=scanners.MultiStringScanner(patterns=[mbr_signature])): try: mbr_start_offset = offset - (mbr_length - len(mbr_signature)) partition_table = self.context.object(partition_table_object, offset=mbr_start_offset, layer_name=layer.name) # Extract only BootCode full_mbr = layer.read(mbr_start_offset, mbr_length, pad=True) bootcode = full_mbr[:bootcode_length] all_zeros = None if bootcode: all_zeros = bootcode.count(b"\x00") == len(bootcode) if not all_zeros: partition_entries = [ partition_table.FirstEntry, partition_table.SecondEntry, partition_table.ThirdEntry, partition_table.FourthEntry ] if not self.config.get("full", True): yield (0, (format_hints.Hex(offset), partition_table.get_disk_signature(), self.get_hash(bootcode), self.get_hash(full_mbr), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), interfaces.renderers.Disassembly( bootcode, 0, architecture))) else: yield (0, (format_hints.Hex(offset), partition_table.get_disk_signature(), self.get_hash(bootcode), self.get_hash(full_mbr), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), renderers.NotApplicableValue(), interfaces.renderers.Disassembly( bootcode, 0, architecture), format_hints.HexBytes(bootcode))) for partition_index, partition_entry_object in enumerate( partition_entries, start=1): if not self.config.get("full", True): yield (1, ( format_hints.Hex(offset), partition_table.get_disk_signature(), self.get_hash(bootcode), self.get_hash(full_mbr), partition_index, partition_entry_object.is_bootable(), partition_entry_object.get_partition_type(), format_hints.Hex(partition_entry_object. get_size_in_sectors()), renderers.NotApplicableValue())) else: yield (1, ( format_hints.Hex(offset), partition_table.get_disk_signature(), self.get_hash(bootcode), self.get_hash(full_mbr), partition_index, partition_entry_object.is_bootable(), format_hints.Hex(partition_entry_object. get_bootable_flag()), partition_entry_object.get_partition_type(), format_hints.Hex( partition_entry_object.PartitionType), format_hints.Hex( partition_entry_object.get_starting_lba()), partition_entry_object.get_starting_cylinder(), partition_entry_object.get_starting_chs(), partition_entry_object.get_starting_sector(), partition_entry_object.get_ending_cylinder(), partition_entry_object.get_ending_chs(), partition_entry_object.get_ending_sector(), format_hints.Hex(partition_entry_object. get_size_in_sectors()), renderers.NotApplicableValue(), renderers.NotApplicableValue())) else: vollog.log( constants.LOGLEVEL_VVVV, f"Not a valid MBR: Data all zeroed out : {format_hints.Hex(offset)}" ) continue except exceptions.PagedInvalidAddressException as excp: vollog.log( constants.LOGLEVEL_VVVV, f"Invalid address identified in guessed MBR: {hex(excp.invalid_address)}" ) continue