def glob_registry_value(key: WinRegistryKey, search_value: str) -> List[str]: """ Globs wildcards in registry value names to a list of names :param key: regf-registry key :param search_value: str, can contain wildcard :return: list of str """ if not key or not search_value: return [] matches = [] value_regex = re.compile(search_value.replace('*', '.*').lower()) for value in key.GetValues(): if value is None or value.name is None: continue if value_regex.match(value.name.lower()): matches.append(value.name) return matches
def _key_to_forensicstore(store: ForensicStore, key: WinRegistryKey, values: Optional[List[str]] = None, artifact: str = '') -> None: """ Export a registry key to the forensicstore, optionally only picking certain values from the key """ last_write_tuple = key.last_written_time.CopyToStatTimeTuple() if last_write_tuple[0]: last_write_date = datetime.utcfromtimestamp(last_write_tuple[0]) last_write_date = last_write_date.replace( microsecond=(int(last_write_tuple[1] / 10))) else: last_write_date = datetime.utcfromtimestamp(0) try: key_item_id = store.add_registry_key_element( artifact=artifact, modified=last_write_date, key=key.path, errors=None) except TypeError as err: LOGGER.exception("Error adding registry key: %s", err) return for value in key.GetValues(): name = value.name if values and name not in values: continue if name is None: name = '(Default)' type_str = value.data_type_string if type_str == 'REG_DWORD_LE': type_str = 'REG_DWORD' # if value.data and (value.DataIsBinaryData() or value.data_type_string == "REG_NONE"): # data = value.data # elif value.data: # data = '{}'.format(value.GetDataAsObject()) # else: # data = b"" try: store.add_registry_value_element(key_item_id, type_str, value.data, name) except sqlite3.OperationalError: LOGGER.exception("Error updating value") continue
def _glob_registry_path_rec( self, keyparts: List[str], level: int, reg_key: WinRegistryKey) -> List[WinRegistryKey]: """ Recursive part of glob_registry_path. Only used internally. :param keyparts[List[str]]: List of registry key parts :param level: current level in the matching (index into keyparts) :param reg_key[RegistryKey]: regf parent key object :return: Recursively calculates all matches and returns List[RegistryKey] """ # catch edge case where no globbing is needed at all if level >= len(keyparts): yield self.system.get_registry().GetKeyByPath('\\'.join(keyparts)) return matches = [] subkeys = reg_key.GetSubkeys() curr_part = keyparts[level] if '*' in curr_part: # this is a location where globbing is needed regex = re.compile(curr_part.replace('*', '.*').lower()) for subkey in subkeys: if regex.match(subkey.name.lower()): matches.append(subkey) else: # no globbing at this point, simple string match for subkey in subkeys: if subkey.name.lower() == curr_part.lower(): matches.append(subkey) # determine if we have checked all parts if level == (len(keyparts) - 1): for match in matches: yield match else: for match in matches: for submatch in self._glob_registry_path_rec( keyparts, level + 1, match): yield submatch