Example #1
0
    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
Example #2
0
    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))
Example #3
0
    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
Example #4
0
    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
Example #5
0
 def get_exit_time(self):
     return conversion.wintime_to_datetime(self.ExitTime.QuadPart)
Example #6
0
 def get_create_time(self):
     return conversion.wintime_to_datetime(self.CreateTime.QuadPart)
Example #7
0
 def get_time(self):
     wintime = (self.High1Time << 32) | self.LowPart
     return conversion.wintime_to_datetime(wintime)
Example #8
0
    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