def __call__(self, context: interfaces.context.ContextInterface, config_path: str, requirement: interfaces.configuration.RequirementInterface, progress_callback: constants.ProgressCallback = None) -> None: useful = [] sub_config_path = interfaces.configuration.path_join( config_path, requirement.name) if (isinstance(requirement, requirements.TranslationLayerRequirement) and requirement.requirements.get("class", False) and requirement.unsatisfied(context, config_path)): class_req = requirement.requirements["class"] for test in self.tests: if (test.layer_type.__module__ + "." + test.layer_type.__name__ == class_req.config_value( context, sub_config_path)): useful.append(test) # Determine if a class has been chosen # Once an appropriate class has been chosen, attempt to determine the page_map_offset value if ("memory_layer" in requirement.requirements and not requirement.requirements["memory_layer"].unsatisfied( context, sub_config_path)): # Only bother getting the DTB if we don't already have one page_map_offset_path = interfaces.configuration.path_join( sub_config_path, "page_map_offset") if not context.config.get(page_map_offset_path, None): physical_layer_name = requirement.requirements[ "memory_layer"].config_value(context, sub_config_path) if not isinstance(physical_layer_name, str): raise TypeError( "Physical layer name is not a string: {}".format( sub_config_path)) physical_layer = context.layers[physical_layer_name] # Check lower layer metadata first if physical_layer.metadata.get('page_map_offset', None): context.config[ page_map_offset_path] = physical_layer.metadata[ 'page_map_offset'] else: hits = physical_layer.scan(context, PageMapScanner(useful), progress_callback) for test, dtb in hits: context.config[page_map_offset_path] = dtb break else: return None if isinstance( requirement, interfaces.configuration. ConstructableRequirementInterface): requirement.construct(context, config_path) else: for subreq in requirement.requirements.values(): self(context, sub_config_path, subreq)
def __call__(self, context: interfaces.context.ContextInterface, config_path: str, requirement: interfaces.configuration.RequirementInterface, progress_callback=None, optional=False) -> List[str]: # Make sure we import the layers, so they can reconstructed framework.import_files(sys.modules['volatility.framework.layers']) result = [] # type: List[str] if requirement.unsatisfied(context, config_path): # Having called validate at the top level tells us both that we need to dig deeper # but also ensures that TranslationLayerRequirements have got the correct subrequirements if their class is populated subreq_config_path = interfaces.configuration.path_join( config_path, requirement.name) for subreq in requirement.requirements.values(): try: self(context, subreq_config_path, subreq, optional=optional or subreq.optional) except Exception as e: # We don't really care if this fails, it tends to mean the configuration isn't complete for that item vollog.log(constants.LOGLEVEL_VVVV, "Construction Exception occurred: {}".format(e)) invalid = subreq.unsatisfied(context, subreq_config_path) # We want to traverse optional paths, so don't check until we've tried to validate # We also don't want to emit a debug message when a parent is optional, hence the optional parameter if invalid and not (optional or subreq.optional): vollog.log( constants.LOGLEVEL_V, "Failed on requirement: {}".format(subreq_config_path)) result.append( interfaces.configuration.path_join( subreq_config_path, subreq.name)) if result: return result elif isinstance( requirement, interfaces.configuration. ConstructableRequirementInterface): # We know all the subrequirements are filled, so let's populate requirement.construct(context, config_path) if progress_callback is not None: progress_callback(100, "Reconstruction finished") return []