def parse_userassist_data(self, reg_val): """Reads the raw data of a _CM_KEY_VALUE and returns a dict of userassist fields.""" item = { "id": renderers.UnparsableValue(), "count": renderers.UnparsableValue(), "focus": renderers.UnparsableValue(), "time": renderers.UnparsableValue(), "lastupdated": renderers.UnparsableValue(), "rawdata": renderers.UnparsableValue(), } userassist_data = reg_val.decode_data() if userassist_data is None: return item item["rawdata"] = userassist_data if self._win7 is None: # if OS is still unknown at this point, return the default item which just has the rawdata return item if len(userassist_data) < self._userassist_size: return item userassist_layer_name = self.context.layers.free_layer_name( "userassist_buffer") buffer = BufferDataLayer(self.context, self._config_path, userassist_layer_name, userassist_data) self.context.add_layer(buffer) userassist_obj = self.context.object(object_type=self._reg_table_name + constants.BANG + self._userassist_type_name, layer_name=userassist_layer_name, offset=0) if self._win7: item["id"] = renderers.NotApplicableValue() item["count"] = int(userassist_obj.Count) seconds = (userassist_obj.FocusTime + 500) / 1000.0 time = datetime.timedelta( seconds=seconds) if seconds > 0 else userassist_obj.FocusTime item["focus"] = int(userassist_obj.FocusCount) item["time"] = str(time) else: item["id"] = int(userassist_obj.ID) item["count"] = int(userassist_obj.CountStartingAtFive if userassist_obj.CountStartingAtFive < 5 else userassist_obj.CountStartingAtFive - 5) item["focus"] = renderers.NotApplicableValue() item["time"] = renderers.NotApplicableValue() item["lastupdated"] = conversion.wintime_to_datetime( userassist_obj.LastUpdated.QuadPart) return item
def _generator(self, procs): pe_table_name = intermed.IntermediateSymbolTable.create( self.context, self.config_path, "windows", "pe", class_types=pe.class_types) kuser = info.Info.get_kuser_structure(self.context, self.config['primary'], self.config['nt_symbols']) nt_major_version = int(kuser.NtMajorVersion) nt_minor_version = int(kuser.NtMinorVersion) # LoadTime only applies to versions higher or equal to Window 7 (6.1 and higher) dll_load_time_field = (nt_major_version > 6) or ( nt_major_version == 6 and nt_minor_version >= 1) for proc in procs: proc_id = proc.UniqueProcessId proc_layer_name = proc.add_process_layer() for entry in proc.load_order_modules(): BaseDllName = FullDllName = renderers.UnreadableValue() try: BaseDllName = entry.BaseDllName.get_string() # We assume that if the BaseDllName points to an invalid buffer, so will FullDllName FullDllName = entry.FullDllName.get_string() except exceptions.InvalidAddressException: pass if dll_load_time_field: # Versions prior to 6.1 won't have the LoadTime attribute # and 32bit version shouldn't have the Quadpart according to MSDN try: DllLoadTime = conversion.wintime_to_datetime( entry.LoadTime.QuadPart) except exceptions.InvalidAddressException: DllLoadTime = renderers.UnreadableValue() else: DllLoadTime = renderers.NotApplicableValue() dumped = False if self.config['dump']: filedata = self.dump_pe(self.context, pe_table_name, entry, proc_layer_name) if filedata: filedata.preferred_filename = "pid.{0}.".format( proc_id) + filedata.preferred_filename dumped = True self.produce_file(filedata) yield (0, (proc.UniqueProcessId, proc.ImageFileName.cast( "string", max_length=proc.ImageFileName.vol.count, errors='replace'), format_hints.Hex(entry.DllBase), format_hints.Hex(entry.SizeOfImage), BaseDllName, FullDllName, DllLoadTime, dumped))
def key_iterator( cls, hive: RegistryHive, node_path: Sequence[objects.StructType] = None, recurse: bool = False ) -> Iterable[Tuple[int, bool, datetime.datetime, str, bool, interfaces.objects.ObjectInterface]]: """Walks through a set of nodes from a given node (last one in node_path). Avoids loops by not traversing into nodes already present in the node_path. Args: hive: The registry hive to walk node_path: The list of nodes that make up the recurse: Traverse down the node tree or stay only on the same level Yields: A tuple of results (depth, is_key, last write time, path, volatile, and the node). """ if not node_path: node_path = [hive.get_node(hive.root_cell_offset)] if not isinstance(node_path, list) or len(node_path) < 1: vollog.warning( "Hive walker was not passed a valid node_path (or None)") return node = node_path[-1] key_path_items = [hive] + node_path[1:] key_path = '\\'.join([k.get_name() for k in key_path_items]) if node.vol.type_name.endswith(constants.BANG + '_CELL_DATA'): raise RegistryFormatException( hive.name, "Encountered _CELL_DATA instead of _CM_KEY_NODE") last_write_time = conversion.wintime_to_datetime( node.LastWriteTime.QuadPart) for key_node in node.get_subkeys(): result = (len(node_path), True, last_write_time, key_path, key_node.get_volatile(), key_node) yield result if recurse: if key_node.vol.offset not in [ x.vol.offset for x in node_path ]: try: sub_node_name = key_node.get_name() except exceptions.InvalidAddressException as excp: vollog.debug(excp) continue yield from cls.key_iterator(hive, node_path + [key_node], recurse=recurse) for value_node in node.get_values(): result = (len(node_path), False, last_write_time, key_path, node.get_volatile(), value_node) yield result
def get_create_time(self): dt_obj = conversion.wintime_to_datetime(self.CreateTime.QuadPart) if isinstance(dt_obj, interfaces.renderers.BaseAbsentValue): return dt_obj # return None if the timestamp seems invalid if not (self.MIN_CREATETIME_YEAR < dt_obj.year < self.MAX_CREATETIME_YEAR): return None else: return dt_obj
def get_exit_time(self): return conversion.wintime_to_datetime(self.ExitTime.QuadPart)
def get_create_time(self): return conversion.wintime_to_datetime(self.CreateTime.QuadPart)
def get_time(self): wintime = (self.High1Time << 32) | self.LowPart return conversion.wintime_to_datetime(wintime)
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