Source code for winspsrc.scripts.extract

#!/usr/bin/env python3
"""Script to extract Windows serialized property information."""

import argparse
import logging
import os
import sys
import yaml

from dfvfs.helpers import command_line as dfvfs_command_line
from dfvfs.helpers import volume_scanner as dfvfs_volume_scanner
from dfvfs.lib import errors as dfvfs_errors

import winspsrc

from winspsrc import extractor
from winspsrc import yaml_definitions_file


[docs] def Main(): """Entry point of console script to extract property information. Returns: int: exit code that is provided to sys.exit(). """ argument_parser = argparse.ArgumentParser( description=("Extract Windows serialized property information.") ) argument_parser.add_argument( "-d", "--debug", dest="debug", action="store_true", default=False, help="enable debug output.", ) argument_parser.add_argument( "-w", "--windows_version", "--windows-version", dest="windows_version", action="store", metavar="Windows XP", default=None, help="string that identifies the Windows version.", ) argument_parser.add_argument( "source", nargs="?", action="store", metavar="PATH", default=None, help=( "path of the volume containing C:\\Windows or the filename of " "a storage media image containing the C:\\Windows directory." ), ) options = argument_parser.parse_args() if not options.source: print("Source value is missing.") print("") argument_parser.print_help() print("") return 1 try: with open(options.source, "r", encoding="utf-8") as file_object: source_definitions = list(yaml.safe_load_all(file_object)) except (SyntaxError, UnicodeDecodeError): source_definitions = [ {"source": options.source, "windows_version": options.windows_version} ] logging.basicConfig(level=logging.INFO, format="[%(levelname)s] %(message)s") definitions_file = yaml_definitions_file.YAMLPropertiesDefinitionsFile() data_path = os.path.join(os.path.dirname(winspsrc.__file__), "data") path = os.path.join(data_path, "defined_properties.yaml") defined_property_definitions = {} for property_definition in definitions_file.ReadFromFile(path): lookup_key = property_definition.lookup_key if lookup_key not in defined_property_definitions: defined_property_definitions[lookup_key] = property_definition path = os.path.join(data_path, "observed_properties.yaml") observed_property_definitions = {} for property_definition in definitions_file.ReadFromFile(path): lookup_key = property_definition.lookup_key if lookup_key not in observed_property_definitions: observed_property_definitions[lookup_key] = property_definition path = os.path.join(data_path, "third_party_properties.yaml") third_party_property_definitions = {} for property_definition in definitions_file.ReadFromFile(path): lookup_key = property_definition.lookup_key if lookup_key not in third_party_property_definitions: third_party_property_definitions[lookup_key] = property_definition mediator = dfvfs_command_line.CLIVolumeScannerMediator() volume_scanner_options = dfvfs_volume_scanner.VolumeScannerOptions() volume_scanner_options.partitions = ["all"] volume_scanner_options.snapshots = ["none"] volume_scanner_options.volumes = ["none"] serialized_properties = {} defined_serialized_properties = {} observed_serialized_properties = {} third_party_serialized_properties = {} unknown_serialized_properties = {} for source_definition in source_definitions: source_path = source_definition["source"] logging.info(f"Processing: {source_path:s}") extractor_object = extractor.SerializedPropertyExtractor( debug=options.debug, mediator=mediator ) try: result = extractor_object.ScanForWindowsVolume( source_path, options=volume_scanner_options ) except dfvfs_errors.ScannerError: result = False if not result: print( ( f"Unable to retrieve the volume with the Windows directory " f"from: {source_path:s}." ) ) print("") return 1 if extractor_object.windows_version: windows_version = extractor_object.windows_version logging.info(f"Detected Windows version: {windows_version:s}") if source_definition["windows_version"]: windows_version = source_definition["windows_version"] else: print("Unable to determine Windows version.") windows_version = source_definition["windows_version"] for serialized_property in extractor_object.CollectSerializedProperies(): lookup_key = serialized_property.lookup_key if lookup_key in serialized_properties: # TODO: check if property is different from existing continue serialized_properties[lookup_key] = serialized_property property_definition = observed_property_definitions.get(lookup_key) if property_definition: observed_serialized_properties[lookup_key] = serialized_property continue property_definition = defined_property_definitions.get(lookup_key) if property_definition: defined_serialized_properties[lookup_key] = serialized_property continue property_definition = third_party_property_definitions.get(lookup_key, None) if property_definition: third_party_serialized_properties[lookup_key] = serialized_property continue unknown_serialized_properties[lookup_key] = serialized_property if observed_serialized_properties: print("Observed properties:") for lookup_key, serialized_property in sorted( observed_serialized_properties.items() ): property_definition = observed_property_definitions.get(lookup_key) print(f"\t{lookup_key:s}", end="") if property_definition and property_definition.shell_property_keys: shell_property_keys = ", ".join(property_definition.shell_property_keys) print(f" ({shell_property_keys:s})", end="") if serialized_property.value_type: print(f" [0x{serialized_property.value_type:04x}]", end="") if not property_definition or serialized_property.value_type not in ( property_definition.value_types ): print(" (undefined value type)", end="") print("") print("") if defined_serialized_properties: print("Defined properties:") for lookup_key, serialized_property in sorted( defined_serialized_properties.items() ): property_definition = defined_property_definitions.get(lookup_key) print(f"\t{lookup_key:s}", end="") if property_definition and property_definition.shell_property_keys: shell_property_keys = ", ".join(property_definition.shell_property_keys) print(f" ({shell_property_keys:s})", end="") if serialized_property.value_type: print(f" [0x{serialized_property.value_type:04x}]", end="") if not property_definition or serialized_property.value_type not in ( property_definition.value_types ): print(" (undefined value type)", end="") print("") print("") if third_party_serialized_properties: print("Third party properties:") for lookup_key, serialized_property in sorted( third_party_serialized_properties.items() ): property_definition = third_party_property_definitions.get(lookup_key, None) print(f"\t{lookup_key:s}", end="") if property_definition and property_definition.shell_property_keys: shell_property_keys = ", ".join(property_definition.shell_property_keys) print(f" ({shell_property_keys:s})", end="") if serialized_property.value_type: print(f" [0x{serialized_property.value_type:04x}]", end="") if not property_definition or serialized_property.value_type not in ( property_definition.value_types ): print(" (undefined value type)", end="") print("") print("") if unknown_serialized_properties: print("Unknown properties:") for lookup_key, serialized_property in sorted( unknown_serialized_properties.items() ): print( ( f"\t{lookup_key:s} [0x{serialized_property.value_type:04x}]" f" ({serialized_property.origin:s})" ) ) print("") return 0
if __name__ == "__main__": sys.exit(Main())