예제 #1
0
    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
예제 #2
0
    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