Пример #1
0
    def __call__(self,
                 context: interfaces.context.ContextInterface,
                 config_path: str,
                 requirement: interfaces.configuration.RequirementInterface,
                 progress_callback: constants.ProgressCallback = None) -> None:
        if requirement.unsatisfied(context, config_path):
            if "pdbscan" not in context.symbol_space:
                context.symbol_space.append(
                    native.NativeTable("pdbscan", native.std_ctypes))
            # TODO: check if this is a windows symbol requirement, otherwise ignore it
            self._symbol_requirements = self.find_requirements(
                context, config_path, requirement,
                requirements.SymbolTableRequirement)
            potential_layers = self.find_virtual_layers_from_req(
                context=context,
                config_path=config_path,
                requirement=requirement)
            for sub_config_path, symbol_req in self._symbol_requirements:
                parent_path = interfaces.configuration.parent_path(
                    sub_config_path)
                if symbol_req.unsatisfied(context, parent_path):
                    valid_kernel = self.determine_valid_kernel(
                        context, potential_layers, progress_callback)
                    if valid_kernel:
                        self.recurse_symbol_fulfiller(context, valid_kernel,
                                                      progress_callback)
                        self.set_kernel_virtual_offset(context, valid_kernel)

        if progress_callback is not None:
            progress_callback(100, "PDB scanning finished")
Пример #2
0
 def _get_natives(self) -> Optional[interfaces.symbols.NativeTableInterface]:
     """Determines the appropriate native_types to use from the JSON
     data."""
     native_dict = {}
     base_types = self._json_object['base_types']
     for base_type in base_types:
         # Void are ignored because voids are not a volatility primitive, they are a specific Volatility object
         if base_type != 'void':
             current = base_types[base_type]
             # TODO: Fix up the typing of this, it bugs out because of the tuple assignment
             if current['kind'] not in self.format_mapping:
                 raise ValueError("Unsupported base kind")
             format_val = (current['size'], current['endian'], current['signed'])
             object_type = self.format_mapping[current['kind']]
             if base_type == 'pointer':
                 object_type = objects.Pointer
             native_dict[base_type] = (object_type, format_val)
     return native.NativeTable(name = "native", native_dictionary = native_dict)
Пример #3
0
    def _read_header(self) -> None:
        """Checks the vmware header to make sure it's valid."""
        if "vmware" not in self._context.symbol_space:
            self._context.symbol_space.append(native.NativeTable("vmware", native.std_ctypes))

        meta_layer = self.context.layers.get(self._meta_layer, None)
        header_size = struct.calcsize(self.header_structure)
        data = meta_layer.read(0, header_size)
        magic, unknown, groupCount = struct.unpack(self.header_structure, data)
        if magic not in [b"\xD0\xBE\xD2\xBE", b"\xD1\xBA\xD1\xBA", b"\xD2\xBE\xD2\xBE", b"\xD3\xBE\xD3\xBE"]:
            raise VmwareFormatException(self.name, "Wrong magic bytes for Vmware layer: {}".format(repr(magic)))

        version = magic[0] & 0xf
        group_size = struct.calcsize(self.group_structure)

        groups = {}
        for group in range(groupCount):
            name, tag_location, _unknown = struct.unpack(
                self.group_structure, meta_layer.read(header_size + (group * group_size), group_size))
            name = name.rstrip(b"\x00")
            groups[name] = tag_location
        memory = groups[b"memory"]

        tags_read = False
        offset = memory
        tags = {}
        index_len = self._context.symbol_space.get_type("vmware!unsigned int").size
        while not tags_read:
            flags = ord(meta_layer.read(offset, 1))
            name_len = ord(meta_layer.read(offset + 1, 1))
            tags_read = (flags == 0) and (name_len == 0)
            if not tags_read:
                name = self._context.object("vmware!string",
                                            layer_name = self._meta_layer,
                                            offset = offset + 2,
                                            max_length = name_len)
                indices_len = (flags >> 6) & 3
                indices = []
                for index in range(indices_len):
                    indices.append(
                        self._context.object("vmware!unsigned int",
                                             offset = offset + name_len + 2 + (index * index_len),
                                             layer_name = self._meta_layer))
                data_len = flags & 0x3f
                
                if data_len in [62, 63]:  # Handle special data sizes that indicate a longer data stream
                    data_len = 4 if version == 0 else 8
                    # Read the size of the data
                    data_size = self._context.object(self._choose_type(data_len),
                                            layer_name = self._meta_layer,
                                            offset = offset + 2 + name_len + (indices_len * index_len))
                    # Skip two bytes of padding (as it seems?)
                    # Read the actual data
                    data = self._context.object("vmware!bytes",
                                                layer_name = self._meta_layer,
                                                offset = offset + 2 + name_len + (indices_len * index_len) +
                                                         2 * data_len + 2,
                                                length = data_size)
                    offset += 2 + name_len + (indices_len * index_len) + 2 * data_len + 2 + data_size
                else:  # Handle regular cases
                    data = self._context.object(self._choose_type(data_len),
                                                layer_name = self._meta_layer,
                                                offset = offset + 2 + name_len + (indices_len * index_len))
                    offset += 2 + name_len + (indices_len * index_len) + data_len

                tags[(name, tuple(indices))] = (flags, data)

        if tags[("regionsCount", ())][1] == 0:
            raise VmwareFormatException(self.name, "VMware VMEM is not split into regions")
        for region in range(tags[("regionsCount", ())][1]):
            offset = tags[("regionPPN", (region, ))][1] * self._page_size
            mapped_offset = tags[("regionPageNum", (region, ))][1] * self._page_size
            length = tags[("regionSize", (region, ))][1] * self._page_size
            self._segments.append((offset, mapped_offset, length, length))