def build_dtb_layer(cls, context, layer_name, progress_callback, banner, symbol_files): join = interfaces.configuration.path_join layer, dtb = (None, None) if symbol_files is None: return layer, dtb isf_path = symbol_files[0] table_name = context.symbol_space.free_table_name('LintelStacker') table = linux.LinuxKernelIntermedSymbols(context, 'temporary.' + table_name, name=table_name, isf_url=isf_path) context.symbol_space.append(table) kaslr_shift, _ = LinuxUtilities.find_aslr( context, table_name, layer_name, progress_callback=progress_callback) layer_class = intel.Intel # type: Type if 'init_top_pgt' in table.symbols: layer_class = intel.Intel32e dtb_symbol_name = 'init_top_pgt' elif 'init_level4_pgt' in table.symbols: layer_class = intel.Intel32e dtb_symbol_name = 'init_level4_pgt' else: dtb_symbol_name = 'swapper_pg_dir' dtb = LinuxUtilities.virtual_to_physical_address( table.get_symbol(dtb_symbol_name).address + kaslr_shift) # Build the new layer new_layer_name = context.layers.free_layer_name("IntelLayer") config_path = join("IntelHelper", new_layer_name) context.config[join(config_path, "memory_layer")] = layer_name context.config[join(config_path, "page_map_offset")] = dtb context.config[join(config_path, LinuxSymbolFinder.banner_config_key)] = str( banner, 'latin-1') layer = layer_class(context, config_path=config_path, name=new_layer_name) return layer, dtb
def stack(cls, context: interfaces.context.ContextInterface, layer_name: str, progress_callback: constants.ProgressCallback = None) -> Optional[interfaces.layers.DataLayerInterface]: """Attempts to identify linux within this layer.""" # Bail out by default unless we can stack properly layer = context.layers[layer_name] join = interfaces.configuration.path_join # Never stack on top of an intel layer # FIXME: Find a way to improve this check if isinstance(layer, intel.Intel): return None linux_banners = LinuxBannerCache.load_banners() # If we have no banners, don't bother scanning if not linux_banners: vollog.info("No Linux banners found - if this is a linux plugin, please check your symbol files location") return None mss = scanners.MultiStringScanner([x for x in linux_banners if x is not None]) for _, banner in layer.scan(context = context, scanner = mss, progress_callback = progress_callback): dtb = None vollog.debug("Identified banner: {}".format(repr(banner))) symbol_files = linux_banners.get(banner, None) if symbol_files: isf_path = symbol_files[0] table_name = context.symbol_space.free_table_name('LintelStacker') table = linux.LinuxKernelIntermedSymbols(context, 'temporary.' + table_name, name = table_name, isf_url = isf_path) context.symbol_space.append(table) kaslr_shift, aslr_shift = cls.find_aslr(context, table_name, layer_name, progress_callback = progress_callback) layer_class = intel.Intel # type: Type if 'init_top_pgt' in table.symbols: layer_class = intel.Intel32e dtb_symbol_name = 'init_top_pgt' elif 'init_level4_pgt' in table.symbols: layer_class = intel.Intel32e dtb_symbol_name = 'init_level4_pgt' else: dtb_symbol_name = 'swapper_pg_dir' dtb = cls.virtual_to_physical_address(table.get_symbol(dtb_symbol_name).address + kaslr_shift) # Build the new layer new_layer_name = context.layers.free_layer_name("IntelLayer") config_path = join("IntelHelper", new_layer_name) context.config[join(config_path, "memory_layer")] = layer_name context.config[join(config_path, "page_map_offset")] = dtb context.config[join(config_path, LinuxSymbolFinder.banner_config_key)] = str(banner, 'latin-1') layer = layer_class(context, config_path = config_path, name = new_layer_name, metadata = {'kaslr_value': aslr_shift}) if layer and dtb: vollog.debug("DTB was found at: 0x{:0x}".format(dtb)) return layer return None