Ejemplo n.º 1
0
 def loadMembers(self, mappings, maxDepth):
     if not ctypes.Structure.loadMembers(self, mappings, maxDepth):
         return False
     # Load and memcopy key and iv
     log.debug('Enc Memcopying a Key with %d bytes'%self.key_len)
     attr_obj_address = get_pointee_address(self.key)
     log.debug('got key @%x '%(attr_obj_address))
     memoryMap = mappings.is_valid_address_value( attr_obj_address)
     # DEBUG - I do question the buffer_copy.
     log.debug('memoryMap is %s - \nmake array '%(memoryMap))
     array=(ctypes.c_ubyte*self.key_len).from_buffer_copy(memoryMap.readArray(attr_obj_address, ctypes.c_ubyte, self.key_len))
     # save key as bitstream
     ##key_contents = ctypes.c_ubyte.from_buffer(array)
     key_contents = array
     log.debug('keep ref ')
     mappings.keepRef(key_contents, utils.get_subtype(self.key), attr_obj_address)
     
     log.debug('Enc Memcopying a IV with %d bytes'%( self.block_size) )
     attr_obj_address=get_pointee_address(self.iv)
     memoryMap = mappings.is_valid_address_value(attr_obj_address)
     log.debug('make array ')
     array=(ctypes.c_ubyte*self.block_size).from_buffer_copy(memoryMap.readArray(attr_obj_address, ctypes.c_ubyte,self.block_size))
     # save iv contents as bitstream
     ##iv_contents = ctypes.c_ubyte.from_buffer(array)
     iv_contents = array
     log.debug('keep ref')
     mappings.keepRef(iv_contents, utils.get_subtype(self.iv), attr_obj_address)
     
     log.debug('ENC KEY(%d bytes) and IV(%d bytes) acquired'%(self.key_len,self.block_size))
     return True
Ejemplo n.º 2
0
    def test_get_subtype(self):
        ctypes = types.reset_ctypes()

        class X(ctypes.Structure):
            _fields_ = [('p', ctypes.POINTER(ctypes.c_long))]
        PX = ctypes.POINTER(X)
        self.assertEquals(utils.get_subtype(PX), X)

        ctypes = types.reload_ctypes(4, 4, 8)  # different arch

        class Y(ctypes.Structure):
            _fields_ = [('p', ctypes.POINTER(ctypes.c_long))]
        PY = ctypes.POINTER(Y)
        self.assertEquals(utils.get_subtype(PY), Y)
Ejemplo n.º 3
0
    def loadMembers(self, mappings, maxDepth):
        if not ctypes.Structure.loadMembers(self, mappings, maxDepth):
            return False
        # Load and memcopy key 
        log.debug('Memcopying a Key with %d bytes'%self.key_len)
        attr_obj_address=get_pointee_address(self.key)
        memoryMap = mappings.is_valid_address_value( attr_obj_address)
        array=(ctypes.c_ubyte*self.key_len).from_buffer_copy(memoryMap.readArray(attr_obj_address, ctypes.c_ubyte, self.key_len))
        mappings.keepRef(array, utils.get_subtype(self.key), attr_obj_address)

        log.debug('unmac_ctx has been nulled and ignored. its not often used by any ssh impl. Not useful for us anyway.')
        log.debug('MAC KEY(%d bytes) acquired'%(self.key_len))
        return True
Ejemplo n.º 4
0
    def loadMembers(self, mappings, maxDepth):
        if not ctypes.Structure.loadMembers(self, mappings, maxDepth):
            return False
        # Load and memcopy key and iv
        log.debug('Enc Memcopying a Key with %d bytes' % self.key_len)
        attr_obj_address = get_pointee_address(self.key)
        log.debug('got key @%x ' % (attr_obj_address))
        memoryMap = mappings.is_valid_address_value(attr_obj_address)
        # DEBUG - I do question the buffer_copy.
        log.debug('memoryMap is %s - \nmake array ' % (memoryMap))
        array = (ctypes.c_ubyte * self.key_len).from_buffer_copy(
            memoryMap.readArray(attr_obj_address, ctypes.c_ubyte,
                                self.key_len))
        # save key as bitstream
        ##key_contents = ctypes.c_ubyte.from_buffer(array)
        key_contents = array
        log.debug('keep ref ')
        mappings.keepRef(key_contents, utils.get_subtype(self.key),
                         attr_obj_address)

        log.debug('Enc Memcopying a IV with %d bytes' % (self.block_size))
        attr_obj_address = get_pointee_address(self.iv)
        memoryMap = mappings.is_valid_address_value(attr_obj_address)
        log.debug('make array ')
        array = (ctypes.c_ubyte * self.block_size).from_buffer_copy(
            memoryMap.readArray(attr_obj_address, ctypes.c_ubyte,
                                self.block_size))
        # save iv contents as bitstream
        ##iv_contents = ctypes.c_ubyte.from_buffer(array)
        iv_contents = array
        log.debug('keep ref')
        mappings.keepRef(iv_contents, utils.get_subtype(self.iv),
                         attr_obj_address)

        log.debug('ENC KEY(%d bytes) and IV(%d bytes) acquired' %
                  (self.key_len, self.block_size))
        return True
Ejemplo n.º 5
0
    def loadMembers(self, mappings, maxDepth):
        if not ctypes.Structure.loadMembers(self, mappings, maxDepth):
            return False
        # Load and memcopy key
        log.debug('Memcopying a Key with %d bytes' % self.key_len)
        attr_obj_address = get_pointee_address(self.key)
        memoryMap = mappings.is_valid_address_value(attr_obj_address)
        array = (ctypes.c_ubyte * self.key_len).from_buffer_copy(
            memoryMap.readArray(attr_obj_address, ctypes.c_ubyte,
                                self.key_len))
        mappings.keepRef(array, utils.get_subtype(self.key), attr_obj_address)

        log.debug(
            'unmac_ctx has been nulled and ignored. its not often used by any ssh impl. Not useful for us anyway.'
        )
        log.debug('MAC KEY(%d bytes) acquired' % (self.key_len))
        return True
Ejemplo n.º 6
0
 def getKey(self):
     #return pointer2bytes(self.key,self.key_len)
     return utils.array2bytes(
         mappings.getRef(utils.get_subtype(self.key),
                         get_pointee_address(self.key)))
Ejemplo n.º 7
0
 def getKey(self):
     #return pointer2bytes(self.key,self.key_len)
     return utils.array2bytes( mappings.getRef( utils.get_subtype(self.key), get_pointee_address(self.key)) )
Ejemplo n.º 8
0
 def _attrToPyObject(self, attr, field, attrtype):
     import ctypes
     if ctypes.is_basic_type(attrtype):
         if ctypes.is_basic_ctype(type(attr)):
             obj = attr.value
         else:
             obj = attr
     elif ctypes.is_struct_type(attrtype) or ctypes.is_union_type(attrtype):
         attr._mappings_ = self.mappings
         obj = self.parse(attr)
     elif ctypes.is_array_of_basic_type(attrtype):
         # return a list of int, float, or a char[] to str
         obj = utils.ctypes_to_python_array(attr)
     elif ctypes.is_array_type(attrtype):
         # array of something else than int/byte
         obj = []
         eltyp = type(attr[0])
         for i in range(0, len(attr)):
             obj.append(self._attrToPyObject(attr[i], i, eltyp))
     elif ctypes.is_cstring_type(attrtype):
         obj = self.mappings.getRef(
             ctypes.CString,
             utils.get_pointee_address(
                 attr.ptr))
     elif ctypes.is_function_type(attrtype):
         obj = repr(attr)
     elif ctypes.is_pointer_type(attrtype):
         # get the cached Value of the LP.
         _subtype = get_subtype(attrtype)
         _address = utils.get_pointee_address(attr)
         if _address == 0:
             # Null pointer
             obj = None
         elif ctypes.is_pointer_to_void_type(attrtype):
             # TODO: make a prototype for c_void_p loading
             # void types a rereturned as None
             obj = None
         elif ctypes.is_array_of_basic_type(attrtype):
             log.error('basic Type array - %s' % (field))
             obj = 'BasicType array'
         else:
             # get the cached Value of the LP.
             _subtype = get_subtype(attrtype)
             cache = self.mappings.getRef(_subtype, _address)
             if cache is not None:  # struct, union...
                 obj = self._attrToPyObject(cache, field, _subtype)
             else:
                 # you got here because your pointer is not loaded:
                 #  did you ignore it in expectedValues ?
                 #  is it in the middle of a struct ?
                 #  is that a linked list ?
                 #  is it a invalid instance ?
                 log.debug('Pointer for field:%s %s/%s not in cache '
                           '0x%x' % (field, attrtype, get_subtype(attrtype),
                                     _address))
                 return (None, None)
     elif isinstance(attr, numbers.Number):
         # case for int, long. But needs to be after c_void_p pointers case
         obj = attr
     else:
         log.error('toPyObj default to return attr %s' % (type(attr)))
         obj = attr
     return obj
Ejemplo n.º 9
0
    def _loadMember(self, attr, attrname, attrtype, mappings, maxDepth):
        ctypes = self._mappings_.config.ctypes
        # skip static void_p data members
        if not self._isLoadableMember(attr, attrname, attrtype):
            log.debug("%s %s not loadable bool(attr) = %s" % (attrname, attrtype,
                                                              bool(attr)))
            return True
        # load it, fields are valid
        elif ctypes.is_struct_type(attrtype) or ctypes.is_union_type(attrtype):
            # its an embedded record. Bytes are already loaded.
            offset = utils.offsetof(type(self), attrname)
            log.debug('st: %s %s is STRUCT at @%x' % (attrname, attrtype,
                                                      self._orig_address_ + offset))
            # TODO pydoc for impl.
            attr._orig_address_ = self._orig_address_ + offset
            attr._mappings = mappings
            if not attr.loadMembers(mappings, maxDepth - 1):
                log.debug(
                    "st: %s %s not valid, error while loading inner struct" %
                    (attrname, attrtype))
                return False
            log.debug("st: %s %s inner struct LOADED " % (attrname, attrtype))
            return True
        elif ctypes.is_array_of_basic_type(attrtype):
            return True
        elif ctypes.is_array_type(attrtype):
            log.debug('a: %s is arraytype %s recurse load' % (attrname,
                                                              repr(attr)))
            attrLen = len(attr)
            if attrLen == 0:
                return True
            elType = type(attr[0])
            for i in range(0, attrLen):
                # FIXME BUG DOES NOT WORK
                # offsetof("%s[%d]") is called, and %s exists, not %s[%d]
                # if not self._loadMember(attr[i], "%s[%d]"%(attrname,i),
                # elType, mappings, maxDepth):
                if not self._loadMember(
                        attr[i], attrname, elType, mappings, maxDepth):
                    return False
            return True
        # we have PointerType here . Basic or complex
        # exception cases
        elif ctypes.is_function_type(attrtype):
            pass
            # FIXME
        elif ctypes.is_cstring_type(attrtype):
            # can't use basic c_char_p because we can't load in foreign memory
            # FIXME, you need to keep a ref to this ctring if
            # your want _mappings_ to exists
            # or just mandate mappings in toString
            attr_obj_address = utils.get_pointee_address(attr.ptr)
            if not bool(attr_obj_address):
                log.debug('%s %s is a CString, the pointer is null (validation '
                          'must have occurred earlier)' % (attrname, attr))
                return True
            memoryMap = mappings.is_valid_address_value(attr_obj_address)
            if not memoryMap:
                log.warning('Error on addr while fetching a CString.'
                            'should not happen')
                return False
            ref = mappings.getRef(ctypes.CString, attr_obj_address)
            if ref:
                log.debug("%s %s loading from references cache %s/0x%lx" % (attrname,
                                                                            attr, ctypes.CString, attr_obj_address))
                return True
            max_size = min(
                self.MAX_CSTRING_SIZE,
                memoryMap.end -
                attr_obj_address)
            log.debug('%s %s is defined as a CString, loading %d bytes from 0x%lx '
                      'is_valid_address %s' % (attrname, attr, max_size, attr_obj_address,
                                               mappings.is_valid_address_value(attr_obj_address)))
            txt, truncated = memoryMap.readCString(attr_obj_address, max_size)
            if truncated:
                log.warning(
                    'buffer size was too small for this CString: %d' %
                    (max_size))

            # that will SEGFAULT attr.string = txt - instead keepRef to String
            mappings.keepRef(txt, ctypes.CString, attr_obj_address)
            log.debug(
                'kept CString ref for "%s" at @%x' %
                (txt, attr_obj_address))
            return True
        # not functionType, it's not loadable
        elif ctypes.is_pointer_type(attrtype):
            _attrType = get_subtype(attrtype)
            attr_obj_address = utils.get_pointee_address(attr)
            ####
            # memcpy and save objet ref + pointer in attr
            # we know the field is considered valid, so if it's not in
            # memory_space, we can ignore it
            memoryMap = mappings.is_valid_address(attr, _attrType)
            if(not memoryMap):
                # big BUG Badaboum, why did pointer changed validity/value ?
                log.warning(
                    "%s %s not loadable 0x%lx but VALID " %
                    (attrname, attr, attr_obj_address))
                return True

            ref = mappings.getRef(_attrType, attr_obj_address)
            if ref:
                log.debug(
                    "%s %s loading from references cache %s/0x%lx" %
                    (attrname, attr, _attrType, attr_obj_address))
                # DO NOT CHANGE STUFF SOUPID attr.contents = ref. attr.contents
                # will SEGFAULT
                return True
            log.debug(
                "%s %s loading from 0x%lx (is_valid_address: %s)" %
                (attrname, attr, attr_obj_address, memoryMap))
            # Read the struct in memory and make a copy to play with.
            # DO NOT COPY THE STRUCT, we have a working readStruct for that...
            # ERRROR
            # attr.contents=_attrType.from_buffer_copy(memoryMap.readStruct(attr_obj_address,
            # _attrType ))
            contents = memoryMap.readStruct(attr_obj_address, _attrType)

            # save that validated and loaded ref and original addr so we dont
            # need to recopy it later
            mappings.keepRef(contents, _attrType, attr_obj_address)
            log.debug(
                "keepRef %s.%s @%x" %
                (_attrType, attrname, attr_obj_address))
            log.debug(
                "%s %s loaded memcopy from 0x%lx to 0x%lx" %
                (attrname,
                 attr,
                 attr_obj_address,
                 (utils.get_pointee_address(attr))))
            # recursive validation checks on new struct
            if not bool(attr):
                log.warning(
                    'Member %s is null after copy: %s' %
                    (attrname, attr))
                return True
            # go and load the pointed struct members recursively
            subtype = utils.get_subtype(attrtype)
            if (ctypes.is_basic_type(subtype) or
                    ctypes.is_array_of_basic_type(subtype)):
                # do nothing
                return True
            elif (ctypes.is_array_type(subtype) or
                  ctypes.is_pointer_type(subtype)):
                return self._loadMember(
                    contents, 'pointee', subtype, mappings, maxDepth - 1)

            if not contents.loadMembers(mappings, maxDepth - 1):
                log.debug('member %s was not loaded' % (attrname))
                # invalidate the cache ref.
                mappings.delRef(_attrType, attr_obj_address)
                return False
            return True
        # TATAFN
        return True
Ejemplo n.º 10
0
 def _isValidAttr(self, attr, attrname, attrtype, mappings):
     """ Validation of a single member """
     import ctypes
     # a)
     log.debug('valid: %s, %s' % (attrname, attrtype))
     if ctypes.is_basic_type(attrtype):
         if attrname in self.expectedValues:
             if attr not in self.expectedValues[attrname]:
                 log.debug(
                     'basicType: %s %s %s bad value not in self.expectedValues[attrname]:' %
                     (attrname, attrtype, repr(attr)))
                 return False
         log.debug(
             'basicType: %s %s %s ok' %
             (attrname, attrtype, repr(attr)))
         return True
     # b)
     elif ctypes.is_struct_type(attrtype) or ctypes.is_union_type(attrtype):
         # do i need to load it first ? becaus it should be memcopied with
         # the super()..
         if not attr.isValid(mappings):
             log.debug(
                 'structType: %s %s %s isValid FALSE' %
                 (attrname, attrtype, repr(attr)))
             return False
         log.debug(
             'structType: %s %s %s isValid TRUE' %
             (attrname, attrtype, repr(attr)))
         return True
     # c)
     elif ctypes.is_array_of_basic_type(attrtype):
         if attrname in self.expectedValues:
             if attr not in self.expectedValues[attrname]:
                 log.debug(
                     'basicArray: %s %s %s - bad value not in self.expectedValues[attrname]:' %
                     (attrname, attrtype, type(attr)))
                 return False
         log.debug(
             'basicArray: %s is arraytype %s we decided it was valid',
             attrname,
             type(attr))
         return True
     # d)
     elif ctypes.is_array_type(attrtype):
         log.debug('array: %s is arraytype %s recurse validate' % (attrname,
                                                                   repr(attr)))
         attrLen = len(attr)
         if attrLen == 0:
             return True
         elType = type(attr[0])
         for i in range(0, attrLen):
             # FIXME BUG DOES NOT WORK - offsetof("%s[%d]") is called,
             # and %s exists, not %s[%d]
             if not self._isValidAttr(attr[i], "%s[%d]" % (attrname, i), elType,
                                      mappings):
                 return False
         return True
     # e)
     elif ctypes.is_cstring_type(attrtype):
         myaddress = utils.get_pointee_address(attr.ptr)
         if attrname in self.expectedValues:
             # test if NULL is an option
             if not bool(myaddress):
                 if not ((None in self.expectedValues[attrname]) or
                         (0 in self.expectedValues[attrname])):
                     log.debug('str: %s %s %s isNULL - NOT EXPECTED' % (
                         attrname, attrtype, repr(attr)))
                     return False
                 log.debug('str: %s %s %s isNULL - OK' % (attrname, attrtype,
                                                          repr(attr)))
                 # e.1)
                 return True
         if (myaddress != 0 and
                 not mappings.is_valid_address_value(myaddress)):
             log.debug('str: %s %s %s 0x%lx INVALID' % (attrname, attrtype,
                                                        repr(attr), myaddress))
             # e.2)
             return False
         log.debug('str: %s %s %s is at 0x%lx OK' % (attrname, attrtype,
                                                     repr(attr), myaddress))
         # e.3)
         return True
     # f)
     elif ctypes.is_pointer_type(attrtype):
         myaddress = utils.get_pointee_address(attr)
         if attrname in self.expectedValues:
             # test if NULL is an option
             log.debug('ctypes.is_pointer_type: bool(attr):%s attr:%s' % (
                 bool(attr), attr))
             if not bool(myaddress):
                 if not ((None in self.expectedValues[attrname]) or
                         (0 in self.expectedValues[attrname])):
                     log.debug('ptr: %s %s %s isNULL - NOT EXPECTED' % (
                         attrname, attrtype, repr(attr)))
                     # f.1) expectedValues specifies NULL to be invalid
                     return False
                 log.debug('ptr: %s %s %s isNULL - OK' % (attrname, attrtype,
                                                          repr(attr)))
                 # f.2) expectedValues specifies NULL to be valid
                 return True
         _attrType = None
         if (ctypes.is_pointer_to_void_type(attrtype) or
                 ctypes.is_function_type(attrtype)):
             log.debug(
                 'Its a simple type. Checking mappings only. attr=%s' %
                 (attr))
             if (myaddress != 0 and
                     not mappings.is_valid_address_value(myaddress)):
                 log.debug('voidptr: %s %s %s 0x%lx INVALID simple pointer' % (
                     attrname, attrtype, repr(attr), myaddress))
                 # f.3) address must be valid, no type requirement
                 return False
         else:
             # test valid address mapping
             _attrType = get_subtype(attrtype)
         if (myaddress != 0 and
                 not mappings.is_valid_address(attr, _attrType)):
             log.debug('ptr: %s %s %s 0x%lx INVALID' % (attrname, attrtype,
                                                        repr(attr), utils.get_pointee_address(attr)))
             # f.4) its a pointer, but not valid in our mappings for this
             # pointee type.
             return False
         log.debug('ptr: name:%s repr:%s address:0x%lx OK' % (attrname,
                                                              repr(attr), utils.get_pointee_address(attr)))
         # f.5) null is accepted by default
         return True
     # g)
     log.error('What type are You ?: %s/%s' % (attrname, attrtype))
     return True