Example #1
0
 def determine_extended_value(self, leaf_type: interfaces.objects.ObjectInterface,
                              value: interfaces.objects.ObjectInterface, module: interfaces.context.ModuleInterface,
                              length: int) -> Tuple[str, interfaces.objects.ObjectInterface, int]:
     """Reads a value and potentially consumes more data to construct the
     value."""
     excess = 0
     if value >= leaf_type.LF_CHAR:
         sub_leaf_type = self.context.object(self.context.symbol_space.get_enumeration(leaf_type.vol.type_name),
                                             layer_name = leaf_type.vol.layer_name,
                                             offset = value.vol.offset)
         # Set the offset at just after the previous size type
         offset = value.vol.offset + value.vol.data_format.length
         if sub_leaf_type in [leaf_type.LF_CHAR]:
             value = module.object(object_type = 'char', offset = offset)
         elif sub_leaf_type in [leaf_type.LF_SHORT]:
             value = module.object(object_type = 'short', offset = offset)
         elif sub_leaf_type in [leaf_type.LF_USHORT]:
             value = module.object(object_type = 'unsigned short', offset = offset)
         elif sub_leaf_type in [leaf_type.LF_LONG]:
             value = module.object(object_type = 'long', offset = offset)
         elif sub_leaf_type in [leaf_type.LF_ULONG]:
             value = module.object(object_type = 'unsigned long', offset = offset)
         else:
             raise TypeError("Unexpected extended value type")
         excess = value.vol.data_format.length
         # Updated the consume/offset counters
     name = module.object(object_type = "string", offset = value.vol.offset + value.vol.data_format.length)
     name_str = self.parse_string(name, leaf_type < leaf_type.LF_ST_MAX, size = length - excess)
     return name_str, value, excess
Example #2
0
    def _enumerate_system_va_type(cls, large_page_size: int, system_range_start: int,
                                  module: interfaces.context.ModuleInterface,
                                  type_array: interfaces.objects.ObjectInterface) -> Dict[str, List[Tuple[int, int]]]:
        result = {}  # type: Dict[str, List[Tuple[int, int]]]
        system_va_type = module.get_enumeration('_MI_SYSTEM_VA_TYPE')
        start = system_range_start
        prev_entry = -1
        cur_size = large_page_size
        for entry in type_array:
            entry = system_va_type.lookup(entry)
            if entry != prev_entry:
                region_range = result.get(entry, [])
                region_range.append((start, cur_size))
                result[entry] = region_range
                start = start + cur_size
                cur_size = large_page_size
            else:
                cur_size += large_page_size
            prev_entry = entry

        return result
Example #3
0
    def consume_type(
        self, module: interfaces.context.ModuleInterface, offset: int,
        length: int
    ) -> Tuple[Tuple[
            Optional[interfaces.objects.ObjectInterface], Optional[str], Union[
                None, List, interfaces.objects.ObjectInterface]], int]:
        """Returns a (leaf_type, name, object) Tuple for a type, and the number
        of bytes consumed."""
        result = None, None, None  # type: Tuple[Optional[interfaces.objects.ObjectInterface], Optional[str], Optional[Union[List, interfaces.objects.ObjectInterface]]]
        leaf_type = self.context.object(module.get_enumeration("LEAF_TYPE"),
                                        layer_name=module._layer_name,
                                        offset=offset)
        consumed = leaf_type.vol.base_type.size
        remaining = length - consumed

        if leaf_type in [
                leaf_type.LF_CLASS, leaf_type.LF_CLASS_ST,
                leaf_type.LF_STRUCTURE, leaf_type.LF_STRUCTURE_ST,
                leaf_type.LF_INTERFACE
        ]:
            structure = module.object(object_type="LF_STRUCTURE",
                                      offset=offset + consumed)
            name_offset = structure.name.vol.offset - structure.vol.offset
            name, value, excess = self.determine_extended_value(
                leaf_type, structure.size, module, remaining - name_offset)
            structure.size = value
            structure.name = name
            consumed += remaining
            result = leaf_type, name, structure
        elif leaf_type in [leaf_type.LF_MEMBER, leaf_type.LF_MEMBER_ST]:
            member = module.object(object_type="LF_MEMBER",
                                   offset=offset + consumed)
            name_offset = member.name.vol.offset - member.vol.offset
            name, value, excess = self.determine_extended_value(
                leaf_type, member.offset, module, remaining - name_offset)
            member.offset = value
            member.name = name
            result = leaf_type, name, member
            consumed += member.vol.size + len(name) + 1 + excess
        elif leaf_type in [
                leaf_type.LF_ARRAY, leaf_type.LF_ARRAY_ST,
                leaf_type.LF_STRIDED_ARRAY
        ]:
            array = module.object(object_type="LF_ARRAY",
                                  offset=offset + consumed)
            name_offset = array.name.vol.offset - array.vol.offset
            name, value, excess = self.determine_extended_value(
                leaf_type, array.size, module, remaining - name_offset)
            array.size = value
            array.name = name
            result = leaf_type, name, array
            consumed += remaining
        elif leaf_type in [leaf_type.LF_ENUMERATE]:
            enum = module.object(object_type='LF_ENUMERATE',
                                 offset=offset + consumed)
            name_offset = enum.name.vol.offset - enum.vol.offset
            name, value, excess = self.determine_extended_value(
                leaf_type, enum.value, module, remaining - name_offset)
            enum.value = value
            enum.name = name
            result = leaf_type, name, enum
            consumed += enum.vol.size + len(name) + 1 + excess
        elif leaf_type in [leaf_type.LF_ARGLIST, leaf_type.LF_ENUM]:
            enum = module.object(object_type="LF_ENUM",
                                 offset=offset + consumed)
            name_offset = enum.name.vol.offset - enum.vol.offset
            name = self.parse_string(enum.name,
                                     leaf_type < leaf_type.LF_ST_MAX,
                                     size=remaining - name_offset)
            enum.name = name
            result = leaf_type, name, enum
            consumed += remaining
        elif leaf_type in [leaf_type.LF_UNION]:
            union = module.object(object_type="LF_UNION",
                                  offset=offset + consumed)
            name_offset = union.name.vol.offset - union.vol.offset
            name = self.parse_string(union.name,
                                     leaf_type < leaf_type.LF_ST_MAX,
                                     size=remaining - name_offset)
            result = leaf_type, name, union
            consumed += remaining
        elif leaf_type in [
                leaf_type.LF_MODIFIER, leaf_type.LF_POINTER,
                leaf_type.LF_PROCEDURE
        ]:
            obj = module.object(object_type=leaf_type.lookup(),
                                offset=offset + consumed)
            result = leaf_type, None, obj
            consumed += remaining
        elif leaf_type in [leaf_type.LF_FIELDLIST]:
            sub_length = remaining
            sub_offset = offset + consumed
            fields = []
            while length > consumed:
                subfield, sub_consumed = self.consume_type(
                    module, sub_offset, sub_length)
                sub_consumed += self.consume_padding(module.layer_name,
                                                     sub_offset + sub_consumed)
                sub_length -= sub_consumed
                sub_offset += sub_consumed
                consumed += sub_consumed
                fields.append(subfield)
            result = leaf_type, None, fields
        elif leaf_type in [leaf_type.LF_BITFIELD]:
            bitfield = module.object(object_type="LF_BITFIELD",
                                     offset=offset + consumed)
            result = leaf_type, None, bitfield
            consumed += remaining
        else:
            raise TypeError("Unhandled leaf_type: {}".format(leaf_type))

        return result, consumed
Example #4
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]]]
        system_va_type = module.get_enumeration('_MI_SYSTEM_VA_TYPE')
        large_page_size = (layer.page_size ** 2) // module.get_type("_MMPTE").size

        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(None, module.name, "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(None, module.name, "Required structures not found")

        return result