Esempio n. 1
0
 def get_type(self, type_name: str) -> interfaces.objects.Template:
     """Resolves an individual symbol."""
     if constants.BANG in type_name:
         index = type_name.find(constants.BANG)
         table_name, type_name = type_name[:index], type_name[index + 1:]
         raise exceptions.SymbolError(
             type_name, table_name,
             "Symbol for a different table requested: {}".format(
                 table_name + constants.BANG + type_name))
     if type_name not in self._json_object['user_types']:
         # Fall back to the natives table
         if type_name in self.natives.types:
             return self.natives.get_type(self.name + constants.BANG +
                                          type_name)
         else:
             raise exceptions.SymbolError(
                 type_name, self.name,
                 "Unknown symbol: {}".format(type_name))
     curdict = self._json_object['user_types'][type_name]
     members = {}
     for member_name in curdict['fields']:
         interdict = curdict['fields'][member_name]
         member = (interdict['offset'],
                   self._interdict_to_template(interdict['type']))
         members[member_name] = member
     object_class = self.get_type_class(type_name)
     if object_class == objects.AggregateType:
         for clazz in objects.AggregateTypes:
             if objects.AggregateTypes[clazz] == curdict['kind']:
                 object_class = clazz
     return objects.templates.ObjectTemplate(type_name=self.name +
                                             constants.BANG + type_name,
                                             object_class=object_class,
                                             size=curdict['size'],
                                             members=members)
Esempio n. 2
0
    def _weak_resolve(self, resolve_type: SymbolType,
                      name: str) -> SymbolSpaceReturnType:
        """Takes a symbol name and resolves it with ReferentialTemplates."""
        if resolve_type == SymbolType.TYPE:
            get_function = 'get_type'
        elif resolve_type == SymbolType.SYMBOL:
            get_function = 'get_symbol'
        elif resolve_type == SymbolType.ENUM:
            get_function = 'get_enumeration'
        else:
            raise TypeError("Weak_resolve called without a proper SymbolType")

        name_array = name.split(constants.BANG)
        if len(name_array) == 2:
            table_name = name_array[0]
            component_name = name_array[1]
            try:
                return getattr(self._dict[table_name],
                               get_function)(component_name)
            except KeyError as e:
                raise exceptions.SymbolError(
                    component_name, table_name,
                    'Type {} references missing Type/Symbol/Enum: {}'.format(
                        name, e))
        raise exceptions.SymbolError(name, None,
                                     "Malformed name: {}".format(name))
Esempio n. 3
0
    def determine_map(cls, module: interfaces.context.ModuleInterface) -> \
            Dict[str, List[Tuple[int, int]]]:
        """Returns the virtual map from a windows kernel module."""
        layer = module.context.layers[module.layer_name]
        if not isinstance(layer, intel.Intel):
            raise

        result = {}  # type: Dict[str, List[Tuple[int, int]]]
        try:
            system_va_type = module.get_enumeration('_MI_SYSTEM_VA_TYPE')
            large_page_size = (layer.page_size**
                               2) // module.get_type("_MMPTE").size
        except exceptions.SymbolError:
            raise exceptions.SymbolError("Required structures not found")

        if module.has_symbol('MiVisibleState'):
            symbol = module.get_symbol('MiVisibleState')
            visible_state = module.object(
                object_type='pointer',
                offset=symbol.address,
                subtype=module.get_type('_MI_VISIBLE_STATE')).dereference()
            if hasattr(visible_state, 'SystemVaRegions'):
                for i in range(visible_state.SystemVaRegions.count):
                    lookup = system_va_type.lookup(i)
                    region_range = result.get(lookup, [])
                    region_range.append(
                        (visible_state.SystemVaRegions[i].BaseAddress,
                         visible_state.SystemVaRegions[i].NumberOfBytes))
                    result[lookup] = region_range
            elif hasattr(visible_state, 'SystemVaType'):
                system_range_start = module.object(
                    object_type="pointer",
                    offset=module.get_symbol("MmSystemRangeStart").address)
                result = cls._enumerate_system_va_type(
                    large_page_size, system_range_start, module,
                    visible_state.SystemVaType)
            else:
                raise exceptions.SymbolError("Required structures not found")
        elif module.has_symbol('MiSystemVaType'):
            system_range_start = module.object(
                object_type="pointer",
                offset=module.get_symbol("MmSystemRangeStart").address)
            symbol = module.get_symbol('MiSystemVaType')
            array_count = (0xFFFFFFFF + 1 -
                           system_range_start) // large_page_size
            type_array = module.object(object_type='array',
                                       offset=symbol.address,
                                       count=array_count,
                                       subtype=module.get_type('char'))

            result = cls._enumerate_system_va_type(large_page_size,
                                                   system_range_start, module,
                                                   type_array)
        else:
            raise exceptions.SymbolError("Required structures not found")

        return result
Esempio n. 4
0
 def get_enumeration(self, enum_name: str) -> interfaces.objects.Template:
     """Look-up a set of enumeration choices from a specific symbol
     table."""
     retval = self._weak_resolve(SymbolType.ENUM, enum_name)
     if not isinstance(retval, interfaces.objects.Template):
         raise exceptions.SymbolError("Unresolvable Enumeration: {}".format(enum_name))
     return retval
Esempio n. 5
0
    def get_type(self, type_name: str) -> interfaces.objects.Template:
        """Resolves an individual symbol."""
        index = type_name.find(constants.BANG)
        if index != -1:
            table_name, type_name = type_name[:index], type_name[index + 1:]
            raise exceptions.SymbolError(
                type_name, table_name,
                "Symbol for a different table requested: {}".format(
                    table_name + constants.BANG + type_name))

        type_definition = self._json_object['user_types'].get(type_name)
        if type_definition is None:
            # Fall back to the natives table
            return self.natives.get_type(self.name + constants.BANG +
                                         type_name)

        members = self._process_fields(type_definition['fields'])

        object_class = self.get_type_class(type_name)
        if object_class == objects.AggregateType:
            for clazz in objects.AggregateTypes:
                if objects.AggregateTypes[clazz] == type_definition['kind']:
                    object_class = clazz
        return objects.templates.ObjectTemplate(type_name=self.name +
                                                constants.BANG + type_name,
                                                object_class=object_class,
                                                size=type_definition['size'],
                                                members=members)
Esempio n. 6
0
    def get_symbol(self, name: str) -> interfaces.symbols.SymbolInterface:
        """Returns the symbol given by the symbol name."""
        if self._symbol_cache.get(name, None):
            return self._symbol_cache[name]
        symbol = self._json_object['symbols'].get(name, None)
        if not symbol:
            raise exceptions.SymbolError(name, self.name,
                                         "Unknown symbol: {}".format(name))
        symbol_type = None
        if 'type' in symbol:
            symbol_type = self._interdict_to_template(symbol['type'])
        symbol_constant_data = None
        if 'constant_data' in symbol:
            symbol_constant_data = base64.b64decode(
                symbol.get('constant_data'))

        # Mask the addresses if necessary
        address = symbol['address'] + self.config.get('symbol_shift', 0)
        if self.config.get('symbol_mask', 0):
            address = address & self.config['symbol_mask']
        self._symbol_cache[name] = interfaces.symbols.SymbolInterface(
            name=name,
            address=address,
            type=symbol_type,
            constant_data=symbol_constant_data)
        return self._symbol_cache[name]
Esempio n. 7
0
 def get_symbol(self,
                symbol_name: str) -> interfaces.symbols.SymbolInterface:
     """Look-up a symbol name across all the contained symbol spaces."""
     retval = self._weak_resolve(SymbolType.SYMBOL, symbol_name)
     if symbol_name not in self._resolved_symbols and retval.type is not None:
         # Stash the old resolved type if it exists
         old_resolved = self._resolved_symbols.get(symbol_name, None)
         try:
             self._resolved_symbols[symbol_name] = retval.type
             for child in retval.type.children:
                 if isinstance(child, objects.templates.ReferenceTemplate):
                     # Resolve the child, then replace it
                     child_resolved = self.get_type(child.vol.type_name)
                     retval.type.replace_child(child, child_resolved)
         finally:
             if old_resolved is not None:
                 self._resolved_symbols[symbol_name] = old_resolved
     if not isinstance(retval, interfaces.symbols.SymbolInterface):
         table_name = None
         index = symbol_name.find(constants.BANG)
         if index > 0:
             table_name, symbol_name = symbol_name[:index], symbol_name[
                 index + 1:]
         raise exceptions.SymbolError(
             symbol_name, table_name,
             "Unresolvable Symbol: {}".format(symbol_name))
     return retval
 def get_enumeration(self, enum_name: str) -> interfaces.objects.Template:
     """Resolves an individual enumeration."""
     if constants.BANG in enum_name:
         raise exceptions.SymbolError(enum_name, self.name,
                                      "Enumeration for a different table requested: {}".format(enum_name))
     if enum_name not in self._json_object['enums']:
         # Fall back to the natives table
         raise exceptions.SymbolError(enum_name, self.name,
                                      "Enumeration not found in {} table: {}".format(self.name, enum_name))
     curdict = self._json_object['enums'][enum_name]
     base_type = self.natives.get_type(curdict['base'])
     # The size isn't actually used, the base-type defines it.
     return objects.templates.ObjectTemplate(type_name = self.name + constants.BANG + enum_name,
                                             object_class = objects.Enumeration,
                                             base_type = base_type,
                                             choices = curdict['constants'])
 def get_symbol(self, name: str) -> interfaces.symbols.SymbolInterface:
     """Returns the location offset given by the symbol name."""
     # TODO: Add the ability to add/remove/change symbols after creation
     # note that this should invalidate/update the cache
     if self._symbol_cache.get(name, None):
         return self._symbol_cache[name]
     symbol = self._json_object['symbols'].get(name, None)
     if not symbol:
         raise exceptions.SymbolError(name, self.name, "Unknown symbol: {}".format(name))
     self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name, address = symbol['address'])
     return self._symbol_cache[name]
Esempio n. 10
0
 def _unresolved(self, *args, **kwargs) -> Any:
     """Referenced symbols must be appropriately resolved before they can
     provide information such as size This is because the size request has
     no context within which to determine the actual symbol structure."""
     type_name = self.vol.type_name.split(constants.BANG)
     table_name = None
     if len(type_name) == 2:
         table_name = type_name[0]
     symbol_name = type_name[-1]
     raise exceptions.SymbolError(
         symbol_name, table_name,
         "Template contains no information about its structure: {}".format(self.vol.type_name))
Esempio n. 11
0
    def get_type(self, type_name: str) -> interfaces.objects.Template:
        """Takes a symbol name and resolves it.

        This method ensures that all referenced templates (including
        self-referential templates) are satisfied as ObjectTemplates
        """
        # Traverse down any resolutions
        if type_name not in self._resolved:
            self._resolved[type_name] = self._weak_resolve(SymbolType.TYPE, type_name)  # type: ignore
            self._iterative_resolve([type_name])
        if isinstance(self._resolved[type_name], objects.templates.ReferenceTemplate):
            raise exceptions.SymbolError("Unresolvable symbol requested: {}".format(type_name))
        return self._resolved[type_name]
Esempio n. 12
0
 def get_symbol(self, name: str) -> interfaces.symbols.SymbolInterface:
     """Returns the symbol given by the symbol name."""
     if self._symbol_cache.get(name, None):
         return self._symbol_cache[name]
     symbol = self._json_object['symbols'].get(name, None)
     if not symbol:
         raise exceptions.SymbolError("Unknown symbol: {}".format(name))
     symbol_type = None
     if 'type' in symbol:
         symbol_type = self._interdict_to_template(symbol['type'])
     self._symbol_cache[name] = interfaces.symbols.SymbolInterface(
         name=name, address=symbol['address'], type=symbol_type)
     return self._symbol_cache[name]
Esempio n. 13
0
 def get_enumeration(self, enum_name: str) -> interfaces.objects.Template:
     """Look-up a set of enumeration choices from a specific symbol
     table."""
     retval = self._weak_resolve(SymbolType.ENUM, enum_name)
     if not isinstance(retval, interfaces.objects.Template):
         table_name = None
         index = enum_name.find(constants.BANG)
         if index > 0:
             table_name, enum_name = enum_name[:index], enum_name[index +
                                                                  1:]
         raise exceptions.SymbolError(
             enum_name, table_name,
             "Unresolvable Enumeration: {}".format(enum_name))
     return retval
Esempio n. 14
0
 def get_symbol(self,
                symbol_name: str) -> interfaces.symbols.SymbolInterface:
     """Look-up a symbol name across all the contained symbol spaces."""
     retval = self._weak_resolve(SymbolType.SYMBOL, symbol_name)
     if symbol_name not in self._resolved_symbols and retval.type is not None:
         self._resolved_symbols[symbol_name] = self._subresolve(retval.type)
     if not isinstance(retval, interfaces.symbols.SymbolInterface):
         table_name = None
         index = symbol_name.find(constants.BANG)
         if index > 0:
             table_name, symbol_name = symbol_name[:index], symbol_name[
                 index + 1:]
         raise exceptions.SymbolError(
             symbol_name, table_name,
             "Unresolvable Symbol: {}".format(symbol_name))
     return retval
Esempio n. 15
0
 def _unresolved(self, *args, **kwargs) -> Any:
     """Referenced symbols must be appropriately resolved before they can
     provide information such as size This is because the size request has
     no context within which to determine the actual symbol structure."""
     raise exceptions.SymbolError("Template contains no information about its structure: {}".format(
         self.vol.type_name))
Esempio n. 16
0
 def get_enumeration(self, name: str) -> objects.Template:
     raise exceptions.SymbolError(name, self.name, "NativeTables never hold enumerations")
Esempio n. 17
0
 def get_symbol(self, name: str) -> SymbolInterface:
     raise exceptions.SymbolError(name, self.name, "NativeTables never hold symbols")