Example #1
0
 def iterateList(self, mappings):
     """ iterate forward, then backward, until null or duplicate """
     done = [0]
     obj = self
     # print 'going forward '
     for fieldname in [forward, backward]:
         link = getattr(obj, fieldname)
         addr = utils.get_pointee_address(link)
         # print fieldname,addr,hex(addr)
         log.debug("iterateList got a <%s>/0x%x" % (link.__class__.__name__, addr))
         nb = 0
         while addr not in done:
             # print '%x %s'%(addr, addr in done)
             done.append(addr)
             memoryMap = mappings.is_valid_address_value(addr, structType)
             if memoryMap == False:
                 log.error("ValueError: 'the link of this linked list has a bad value'")
                 raise StopIteration
             st = memoryMap.readStruct(addr, structType)
             st._orig_address_ = addr
             mappings.keepRef(st, structType, addr)
             log.debug("keepRefx2 %s.%s: @%x" % (structType.__name__, fieldname, addr))
             yield addr
             # next
             link = getattr(st, fieldname)
             addr = utils.get_pointee_address(link)
         # print 'going backward after %x'%(addr)
     raise StopIteration
Example #2
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
Example #3
0
 def __str__(self):
     """Print the direct members values. Never tries to recurse."""
     import ctypes
     if hasattr(self, '_orig_address_'):
         s = "# <%s at @%x>\n" % (
             self.__class__.__name__, self._orig_address_)
     else:
         s = "# <%s at @???>\n" % (self.__class__.__name__)
     # we need to ensure _mappings_ is defined in all children.
     for field, attrtype in self.getFields():
         attr = getattr(self, field)
         if ctypes.is_basic_type(attrtype):
             # basic type, ctypes or python
             s += '%s : %s, \n' % (field, repr(attr))
         elif (ctypes.is_struct_type(attrtype) or
               ctypes.is_union_type(attrtype)):
             # you can print a inner struct content
             s += '%s (@0x%lx) : {\t%s}\n' % (field,
                                              ctypes.addressof(attr),
                                              attr)
         elif ctypes.is_function_type(attrtype):
             # only print address in target space
             s += '%s (@0x%lx) : 0x%lx (FIELD NOT LOADED: function type)\n' % (
                 field, ctypes.addressof(attr),
                 utils.get_pointee_address(attr))
         elif ctypes.is_array_of_basic_type(attrtype):
             try:
                 s += '%s (@0x%lx) : %s\n' % (field, ctypes.addressof(attr),
                                              repr(utils.array2bytes(attr)))
             except IndexError as e:
                 log.error('error while reading %s %s' % (repr(attr),
                                                          type(attr)))
                 # FIXME
         elif ctypes.is_array_type(attrtype):
             # array of something else than int
             s += '%s (@0x%lx)    :[' % (field, ctypes.addressof(attr))
             s += ','.join(["%s" % (val) for val in attr])
             s += '],\n'
         elif ctypes.is_cstring_type(attrtype):
             # only print address/null
             s += '%s (@0x%lx) : 0x%lx\n' % (field, ctypes.addressof(attr),
                                             utils.get_pointee_address(attr.ptr))
         elif ctypes.is_pointer_type(attrtype):  # and
             # not ctypes.is_pointer_to_void_type(attrtype)):
             # do not recurse.
             if attr is None:
                 attr = 0
                 s += '%s (@????) : 0x0\n' % (field)
             else:
                 s += '%s (@0x%lx) : 0x%lx\n' % (field, ctypes.addressof(attr),
                                             utils.get_pointee_address(attr))
         elif (isinstance(attr, long)) or (isinstance(attr, int)):
             s += '%s : %s\n' % (field, hex(attr))
         else:
             s += '%s : %s\n' % (field, repr(attr))
     return s
Example #4
0
def HEAP_get_segment_list(self, mappings):
    """returns a list of all segment attached to one Heap structure."""
    segments = list()
    for segment in self.iterateListField(mappings, 'SegmentList'):
        segment_addr = segment._orig_address_
        first_addr = utils.get_pointee_address(segment.FirstEntry)
        last_addr = utils.get_pointee_address(segment.LastValidEntry)
        log.debug(
            'Heap.Segment: 0x%0.8x FirstEntry: 0x%0.8x LastValidEntry: 0x%0.8x' %
            (segment_addr, first_addr, last_addr))
        segments.append(segment)
    return segments
Example #5
0
    def test_get_pointee_address(self):
        """tests get_pointee_address on host ctypes POINTER and haystack POINTER"""
        ctypes = types.reload_ctypes(8, 8, 16)

        class X(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        self.assertEquals(ctypes.sizeof(X), 17)
        i = X.from_buffer_copy(
            b'\xAA\xAA\xBB\xBB' +
            4 *
            '\xBB' +
            8 *
            '\x11' +
            '\xCC')
        a = utils.get_pointee_address(i.p)
        self.assertEquals(ctypes.sizeof(i.p), 8)
        self.assertNotEquals(a, 0)
        self.assertEquals(a, 0x1111111111111111)  # 8*'\x11'
        # null pointer
        i = X.from_buffer_copy(
            b'\xAA\xAA\xBB\xBB' +
            4 *
            '\xBB' +
            8 *
            '\x00' +
            '\xCC')
        pnull = utils.get_pointee_address(i.p)
        self.assertEquals(utils.get_pointee_address(pnull), 0)

        # change arch, and retry
        ctypes = types.reload_ctypes(4, 4, 8)

        class Y(ctypes.Structure):
            _pack_ = True
            _fields_ = [('a', ctypes.c_long),
                        ('p', ctypes.POINTER(ctypes.c_int)),
                        ('b', ctypes.c_ubyte)]
        self.assertEquals(ctypes.sizeof(Y), 9)
        i = Y.from_buffer_copy(b'\xAA\xAA\xBB\xBB' + 4 * '\x11' + '\xCC')
        a = utils.get_pointee_address(i.p)
        self.assertEquals(ctypes.sizeof(i.p), 4)
        self.assertNotEquals(a, 0)
        self.assertEquals(a, 0x11111111)  # 4*'\x11'
        # null pointer
        i = Y.from_buffer_copy(b'\xAA\xAA\xBB\xBB' + 4 * '\x00' + '\xCC')
        pnull = utils.get_pointee_address(i.p)
        self.assertEquals(utils.get_pointee_address(pnull), 0)

        # non-pointer, and void null pointer
        ctypes = types.load_ctypes_default()
        i = ctypes.c_int(69)
        self.assertEquals(utils.get_pointee_address(i), 0)
        pnull = ctypes.c_void_p(0)
        self.assertEquals(utils.get_pointee_address(pnull), 0)

        pass
Example #6
0
    def loadMembers(self, mappings, maxDepth):
        if not ctypes.Structure.loadMembers(self, mappings, maxDepth):
            return False
        #log.debug('evp        app_data        attr_obj_address=0x%lx'%(self.evp.app_data) )
        #log.debug('evp        cipher_data attr_obj_address=0x%lx'%(self.evp.cipher_data) )    ##none
        cipher = mappings.getRef(Cipher, get_pointee_address(self.cipher))
        ciphername = mappings.getRef(ctypes.CString,
                                     get_pointee_address(cipher.name.ptr))
        # cast evp.app_data into a valid struct
        if ciphername in self.cipherContexts:
            # evp.cipher.nid should be 0
            struct = self.cipherContexts[ciphername]
            if (struct is None):
                log.warning("Unsupported cipher %s" % (ciphername))
                return True
            attr_obj_address = get_pointee_address(self.evp.app_data)
            memoryMap = mappings.is_valid_address_value(
                attr_obj_address, struct)
            log.debug("CipherContext CAST app_data into : %s " % (struct))
            if not memoryMap:
                log.warning(
                    'On second toughts, app_data seems to be at an invalid address. That should not happen (often).'
                )
                log.warning('%s addr:0x%lx size:0x%lx addr+size:0x%lx ' %
                            (mappings.is_valid_address_value(attr_obj_address),
                             attr_obj_address, ctypes.sizeof(struct),
                             attr_obj_address + ctypes.sizeof(struct)))
                return False  # DEBUG kill it
            # read the void * and keep a ref
            st = memoryMap.readStruct(attr_obj_address, struct)
            mappings.keepRef(st, struct, attr_obj_address)
            # yeah... no. "self.evp.app_data = xx" means SEGFAULT.
            address_evp_app_data = ctypes.addressof(st)

            log.debug('Copied 0x%lx into app_data (0x%lx)' %
                      (attr_obj_address, address_evp_app_data))
            log.debug('LOADED app_data as %s from 0x%lx (%s) into 0x%lx' %
                      (struct, attr_obj_address,
                       mappings.is_valid_address_value(
                           attr_obj_address, struct), address_evp_app_data))
            from haystack.outputters import text
            parser = text.RecursiveTextOutputter(mappings)
            log.debug('\t\t---------\n%s\t\t---------' % (parser.parse(st)))
        else:
            log.debug(
                "Unknown cipher %s, can't load a data struct for the EVP_CIPHER_CTX->app_data"
                % (ciphername))
        return True
Example #7
0
def HEAP_SUBSEGMENT_get_freeblocks(self):
    """
    Use AggregateExchg.Depth and NextFreeoffset to fetch the head, then traverse the links
    """
    userblocks_addr = utils.get_pointee_address(self.UserBlocks)
    if not bool(userblocks_addr):
        return []
    # structure is in a structure in an union
    # struct_c__S__INTERLOCK_SEQ_Ua_Sa_0
    aggExchange = self.AggregateExchg._0._0
    if aggExchange.FreeEntryOffset == 0x2:
        log.debug(' * FirstFreeOffset==0x2 Depth==%d' % (aggExchange.Depth))
    # self.AggregateExchg.Depth the size of UserBlock divided by the HeapBucket size
    # self.AggregateExchg.FreeEntryOffset starts at 0x2 (blocks), which means 0x10 bytes after UserBlocks
    # see Understanding LFH page 14
    # nextoffset of user data is at current + offset*8 + len(HEAP_ENTRY)
    # the structure is astructure in an unnamed union of self
    st = self._3._0
    freeblocks = [(userblocks_addr +
                   (aggExchange.FreeEntryOffset *
                    8) +
                   st.BlockSize *
                   8 *
                   i, st.BlockSize *
                   8) for i in range(aggExchange.Depth)]
    return freeblocks
Example #8
0
def HEAP_SUBSEGMENT_get_userblocks(self):
    """
    AggregateExchg contains info on userblocks, number left, depth
    """
    userblocks_addr = utils.get_pointee_address(self.UserBlocks)
    if not bool(userblocks_addr):
        log.debug('Userblocks is null')
        return []
    # the structure is astructure in an unnamed union of self
    st = self._3._0
    # its basically an array of self.BlockCount blocks of self.BlockSize*8
    # bytes.
    log.debug(
        'fetching %d blocks of %d bytes' %
        (st.BlockCount, st.BlockSize * 8))
    # UserBlocks points to HEAP_USERDATA_HEADER. Real user data blocks will starts after sizeof( HEAP_USERDATA_HEADER ) = 0x10
    # each chunk starts with a 8 byte header + n user-writeable data
    # user writable chunk starts with 2 bytes for next offset
    # basically, first committed block is first.
    # ( page 38 )
    userblocks = [
        (userblocks_addr +
         0x10 +
         st.BlockSize *
         8 *
         i,
         st.BlockSize *
         8) for i in range(
            st.BlockCount)]
    #
    # we need to substract non allocated blocks
    # self.AggregateExchg.Depth counts how many blocks are remaining free
    # if self.AggregateExchg.FreeEntryOffset == 0x2, there a are no commited
    # blocks
    return userblocks
Example #9
0
def HEAP_get_chunks(self, mappings):
    """Returns a list of tuple(address,size) for all chunks in
     the backend allocator."""
    allocated = list()
    free = list()
    for segment in self.get_segment_list(mappings):
        first_addr = utils.get_pointee_address(segment.FirstEntry)
        last_addr = utils.get_pointee_address(segment.LastValidEntry)
        # create the skip list for each segment.
        skiplist = dict()
        for ucr in segment.get_UCR_segment_list(mappings):
            ucr_addr = utils.get_pointee_address(ucr.Address)
            # UCR.Size are not chunks sizes. NOT *8
            skiplist[ucr_addr] = ucr.Size
        #
        chunk_addr = first_addr
        while (chunk_addr < last_addr):
            if chunk_addr in skiplist:
                size = skiplist[chunk_addr]
                log.debug(
                    'Skipping 0x%0.8x - skip %0.5x bytes to 0x%0.8x' %
                    (chunk_addr, size, chunk_addr + size))
                chunk_addr += size
                continue
            chunk_header = mappings.getRef(HEAP_ENTRY, chunk_addr)
            if chunk_header is None:  # force read it
                chunk_header = _get_chunk(mappings, self, chunk_addr)
            if self.EncodeFlagMask:  # heap.EncodeFlagMask
                chunk_header = HEAP_ENTRY_decode(chunk_header, self)
            #log.debug('\t\tEntry: 0x%0.8x\n%s'%( chunk_addr, chunk_header))

            if ((chunk_header.Flags & 1) == 1):
                log.debug(
                    'Chunk 0x%0.8x is in use size: %0.5x' %
                    (chunk_addr, chunk_header.Size * 8))
                allocated.append((chunk_addr, chunk_header.Size * 8))
            else:
                log.debug('Chunk 0x%0.8x is FREE' % (chunk_addr))
                free.append((chunk_addr, chunk_header.Size * 8))
                pass
            chunk_addr += chunk_header.Size * 8
    return (allocated, free)
Example #10
0
def EVP_CIPHER_CTX_toPyObject(self):
        d = super(EVP_CIPHER_CTX,self).toPyObject()
        log.debug('Cast a EVP_CIPHER_CTX into PyObj')
        # cast app_data or cipher_data to right struct
        if bool(self.cipher_data):
            cipher = self._mappings_.getRef( evp_cipher_st, get_pointee_address(self.cipher) )
            struct = getCipherDataType( cipher.nid)
            if struct is not None:
                # CAST c_void_p to struct
                d.cipher_data = struct.from_address(self.cipher_data).toPyObject()
        return d
Example #11
0
def HEAP_getFreeLists_by_blocksindex(self, mappings):
    """ Understanding_the_LFH.pdf page 21
    Not Implemented yet
    """
    freeList = []
    # 128 blocks
    start = ctypes.addressof(self.BlocksIndex)
    bi_addr = utils.get_pointee_address(self.BlocksIndex)
    # enumerate BlocksIndex recursively on ExtendedLookup param
    while bi_addr != 0:
        log.debug('BLocksIndex is at %x' % (bi_addr))
        m = mappings.get_mapping_for_address(bi_addr)
        bi = m.readStruct(bi_addr, HEAP_LIST_LOOKUP)
        """
            ('ExtendedLookup', POINTER(HEAP_LIST_LOOKUP)),
            ('ArraySize', __uint32_t),
            ('ExtraItem', __uint32_t),
            ('ItemCount', __uint32_t),
            ('OutOfRangeItems', __uint32_t),
            ('BaseIndex', __uint32_t),
            ('ListHead', POINTER(LIST_ENTRY)),
            ('ListsInUseUlong', POINTER(__uint32_t)),
            ('ListHints', POINTER(POINTER(LIST_ENTRY))),
        """
        log.debug('ArraySize is %d' % (bi.ArraySize))
        log.debug('BlocksIndex: %s' % (bi.toString()))
        hints_addr = utils.get_pointee_address(bi.ListHints)
        log.debug('ListHints is pointing to %x' % (hints_addr))
        extlookup_addr = utils.get_pointee_address(bi.ExtendedLookup)
        log.debug('ExtendedLookup is pointing to %x' % (extlookup_addr))
        if extlookup_addr == 0:
            """ all chunks of size greater than or equal to BlocksIndex->ArraySize - 1 will
            be stored in ascending order in FreeList[ArraySize-BaseIndex – 1] """
            log.debug(
                'Free chunks >= %d stored at FreeList[ArraySize(%d)-BaseIndex(%d) – 1]' %
                (bi.ArraySize - 1, bi.ArraySize, bi.BaseIndex))
            #raise NotImplementedError()
        log.debug('-' * 80)
        bi_addr = extlookup_addr
    #
    raise NotImplementedError('NOT FINISHED')
Example #12
0
def EVP_CIPHER_CTX_toPyObject(self):
    d = super(EVP_CIPHER_CTX, self).toPyObject()
    log.debug('Cast a EVP_CIPHER_CTX into PyObj')
    # cast app_data or cipher_data to right struct
    if bool(self.cipher_data):
        cipher = self._mappings_.getRef(evp_cipher_st,
                                        get_pointee_address(self.cipher))
        struct = getCipherDataType(cipher.nid)
        if struct is not None:
            # CAST c_void_p to struct
            d.cipher_data = struct.from_address(self.cipher_data).toPyObject()
    return d
Example #13
0
def EVP_CIPHER_CTX_loadMembers(self, mappings, maxDepth):
    if not super(EVP_CIPHER_CTX, self).loadMembers(mappings, maxDepth):
        return False
    log.debug('trying to load cipher_data Structs.')
    '''
    if bool(cipher) and bool(self.cipher.nid) and mappings.is_valid_address(cipher_data):
        memcopy( self.cipher_data, cipher_data_addr, self.cipher.ctx_size)
        # cast possible on cipher.nid -> cipherType
    '''
    cipher = mappings.getRef(evp_cipher_st, get_pointee_address(self.cipher))
    if cipher.nid == 0:  # NID_undef, not openssl doing
        log.info(
            'The cipher is home made - the cipher context data should be application dependant (app_data)'
        )
        return True

    struct = getCipherDataType(cipher.nid)
    log.debug('cipher type is %s - loading %s' %
              (getCipherName(cipher.nid), struct))
    if (struct is None):
        log.warning("Unsupported cipher %s" % (cipher.nid))
        return True

    # c_void_p is a basic type.
    attr_obj_address = self.cipher_data
    memoryMap = mappings.is_valid_address_value(attr_obj_address, struct)
    log.debug("cipher_data CAST into : %s " % (struct))
    if not memoryMap:
        log.warning(
            'in CTX On second toughts, cipher_data seems to be at an invalid address. That should not happen (often).'
        )
        log.warning('%s addr:0x%lx size:0x%lx addr+size:0x%lx ' %
                    (mappings.is_valid_address_value(attr_obj_address),
                     attr_obj_address, ctypes.sizeof(struct),
                     attr_obj_address + ctypes.sizeof(struct)))
        return True
    #ok
    st = memoryMap.readStruct(attr_obj_address, struct)
    mappings.keepRef(st, struct, attr_obj_address)
    self.cipher_data = ctypes.c_void_p(ctypes.addressof(st))
    ###print 'self.cipher_data in loadmembers',self.cipher_data
    # check debug
    attr = getattr(self, 'cipher_data')
    log.debug('Copied 0x%lx into %s (0x%lx)' %
              (ctypes.addressof(st), 'cipher_data', attr))
    log.debug(
        'LOADED cipher_data as %s from 0x%lx (%s) into 0x%lx' %
        (struct, attr_obj_address,
         mappings.is_valid_address_value(attr_obj_address, struct), attr))
    from haystack.outputters import text
    parser = text.RecursiveTextOutputter(mappings)
    log.debug('\t\t---------\n%s\t\t---------' % (parser.parse(st)))
    return True
Example #14
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
Example #15
0
def HEAP_SEGMENT_get_UCR_segment_list(self, mappings):
    """Returns a list of UCR segments for this segment.
    HEAP_SEGMENT.UCRSegmentList is a linked list to UCRs for this segment.
    Some may have Size == 0.
    """
    ucrs = list()
    for ucr in self.iterateListField(mappings, 'UCRSegmentList'):
        ucr_struct_addr = ucr._orig_address_
        ucr_addr = utils.get_pointee_address(ucr.Address)
        # UCR.Size are not chunks sizes. NOT *8
        log.debug("Segment.UCRSegmentList: 0x%0.8x addr: 0x%0.8x size: 0x%0.5x" % (
            ucr_struct_addr, ucr_addr, ucr.Size))
        ucrs.append(ucr)
    return ucrs
Example #16
0
 def loadMembers(self, mappings, maxDepth):
     if not ctypes.Structure.loadMembers(self, mappings, maxDepth):
         return False
     #log.debug('evp        app_data        attr_obj_address=0x%lx'%(self.evp.app_data) )
     #log.debug('evp        cipher_data attr_obj_address=0x%lx'%(self.evp.cipher_data) )    ##none
     cipher = mappings.getRef( Cipher, get_pointee_address(self.cipher) )
     ciphername = mappings.getRef(ctypes.CString, get_pointee_address(cipher.name.ptr) )
     # cast evp.app_data into a valid struct
     if ciphername in self.cipherContexts:
         # evp.cipher.nid should be 0
         struct = self.cipherContexts[ciphername]
         if (struct is None):
             log.warning("Unsupported cipher %s"%(ciphername))
             return True
         attr_obj_address = get_pointee_address(self.evp.app_data)
         memoryMap = mappings.is_valid_address_value(attr_obj_address, struct)
         log.debug( "CipherContext CAST app_data into : %s "%( struct) )
         if not memoryMap:
             log.warning('On second toughts, app_data seems to be at an invalid address. That should not happen (often).')
             log.warning('%s addr:0x%lx size:0x%lx addr+size:0x%lx '%(mappings.is_valid_address_value( attr_obj_address), 
                                                                     attr_obj_address, ctypes.sizeof(struct), attr_obj_address+ctypes.sizeof(struct)))
             return False # DEBUG kill it
         # read the void * and keep a ref
         st = memoryMap.readStruct(attr_obj_address, struct )
         mappings.keepRef(st, struct, attr_obj_address)
         # yeah... no. "self.evp.app_data = xx" means SEGFAULT.
         address_evp_app_data = ctypes.addressof(st)
         
         log.debug('Copied 0x%lx into app_data (0x%lx)'%(attr_obj_address, address_evp_app_data) )
         log.debug('LOADED app_data as %s from 0x%lx (%s) into 0x%lx'%(struct, 
                     attr_obj_address, mappings.is_valid_address_value(attr_obj_address,struct), address_evp_app_data))
         from haystack.outputters import text
         parser = text.RecursiveTextOutputter(mappings)
         log.debug('\t\t---------\n%s\t\t---------'%(parser.parse(st)))
     else:
         log.debug("Unknown cipher %s, can't load a data struct for the EVP_CIPHER_CTX->app_data"%(ciphername))
     return True
Example #17
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
Example #18
0
def HEAP_get_free_UCR_segment_list(self, mappings):
    """Returns a list of available UCR segments for this heap.
    HEAP.UCRList is a linked list to all UCRSegments

    """
    # TODO: exclude UCR segment from valid pointer values in mappings.
    ucrs = list()
    for ucr in self.iterateListField(mappings, 'UCRList'):
        ucr_struct_addr = ucr._orig_address_
        ucr_addr = utils.get_pointee_address(ucr.Address)
        # UCR.Size are not chunks sizes. NOT *8
        log.debug("Heap.UCRList: 0x%0.8x addr: 0x%0.8x size: 0x%0.5x" % (
            ucr_struct_addr, ucr_addr, ucr.Size))
        ucrs.append(ucr)
    return ucrs
Example #19
0
    def is_valid_address(self, obj, structType=None):  # FIXME is valid pointer
        """
        :param obj: the obj to evaluate.
        :param structType: the object's type, so the size could be taken in consideration.

        Returns False if the object address is NULL.
        Returns False if the object address is not in a mapping.

        Returns the mapping in which the object stands otherwise.
        """
        # check for null pointers
        addr = utils.get_pointee_address(obj)
        if addr == 0:
            return False
        return self.is_valid_address_value(addr, structType)
Example #20
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
Example #21
0
 def getEvpAppData(self, mappings):
     cipher = self.getCipher(mappings)
     ciphername = cipher.getName(mappings)
     if ciphername in self.cipherContexts:
         struct = self.cipherContexts[ciphername]
         from haystack.outputters import text
         parser = text.RecursiveTextOutputter(mappings)
         if (struct is None):
             log.warning("Unsupported cipher %s" % (ciphername))
             log.warning("%s" % (parser.parse(cipher)))
             return None
         log.debug('CAST evp.app_data Into %s' % (struct))
         attr_obj_address = get_pointee_address(self.evp.app_data)
         st = mappings.getRef(struct, attr_obj_address)
         #st = struct.from_address(attr)
         log.debug('app_data value is : 0x%lx' % (attr_obj_address))
         log.debug(parser.parse(st))
         return st
     return None
Example #22
0
 def getEvpAppData(self, mappings):
     cipher = self.getCipher(mappings)
     ciphername = cipher.getName(mappings)
     if ciphername in self.cipherContexts:
         struct = self.cipherContexts[ciphername]
         from haystack.outputters import text
         parser = text.RecursiveTextOutputter(mappings)
         if(struct is None):
             log.warning("Unsupported cipher %s"%(ciphername))
             log.warning("%s"%(parser.parse(cipher)))
             return None
         log.debug('CAST evp.app_data Into %s'%(struct))
         attr_obj_address = get_pointee_address(self.evp.app_data)
         st = mappings.getRef(struct, attr_obj_address)
         #st = struct.from_address(attr)
         log.debug('app_data value is : 0x%lx'%(attr_obj_address))
         log.debug(parser.parse(st))
         return st
     return None
Example #23
0
def EVP_CIPHER_CTX_loadMembers(self, mappings, maxDepth):
    if not super(EVP_CIPHER_CTX,self).loadMembers(mappings, maxDepth):
        return False
    log.debug('trying to load cipher_data Structs.')
    '''
    if bool(cipher) and bool(self.cipher.nid) and mappings.is_valid_address(cipher_data):
        memcopy( self.cipher_data, cipher_data_addr, self.cipher.ctx_size)
        # cast possible on cipher.nid -> cipherType
    '''
    cipher = mappings.getRef( evp_cipher_st, get_pointee_address(self.cipher) )
    if cipher.nid == 0: # NID_undef, not openssl doing
        log.info('The cipher is home made - the cipher context data should be application dependant (app_data)')
        return True
        
    struct = getCipherDataType( cipher.nid) 
    log.debug('cipher type is %s - loading %s'%( getCipherName(cipher.nid), struct ))
    if(struct is None):
        log.warning("Unsupported cipher %s"%(cipher.nid))
        return True
    
    # c_void_p is a basic type.
    attr_obj_address = self.cipher_data
    memoryMap = mappings.is_valid_address_value( attr_obj_address, struct)
    log.debug( "cipher_data CAST into : %s "%(struct) )
    if not memoryMap:
        log.warning('in CTX On second toughts, cipher_data seems to be at an invalid address. That should not happen (often).')
        log.warning('%s addr:0x%lx size:0x%lx addr+size:0x%lx '%(mappings.is_valid_address_value(attr_obj_address), 
                                                                attr_obj_address, ctypes.sizeof(struct), attr_obj_address+ctypes.sizeof(struct)))
        return True
    #ok
    st = memoryMap.readStruct(attr_obj_address, struct )
    mappings.keepRef(st, struct, attr_obj_address)
    self.cipher_data = ctypes.c_void_p(ctypes.addressof(st)) 
    ###print 'self.cipher_data in loadmembers',self.cipher_data
    # check debug
    attr=getattr(self, 'cipher_data')            
    log.debug('Copied 0x%lx into %s (0x%lx)'%(ctypes.addressof(st), 'cipher_data', attr))            
    log.debug('LOADED cipher_data as %s from 0x%lx (%s) into 0x%lx'%(struct, 
                attr_obj_address, mappings.is_valid_address_value(attr_obj_address, struct), attr ))
    from haystack.outputters import text
    parser = text.RecursiveTextOutputter(mappings)                
    log.debug('\t\t---------\n%s\t\t---------'%(parser.parse(st)))
    return True
Example #24
0
def BIGNUM_loadMembers(self, mappings, maxDepth):
    ''' 
    #self._d = process.readArray(attr_obj_address, ctypes.c_ulong, self.top) 
    ## or        
    #ulong_array= (ctypes.c_ulong * self.top)        
    '''
    if not self.isValid(mappings):
        log.debug('BigNUm tries to load members when its not validated')
        return False
    # Load and memcopy d / BN_ULONG *
    attr_obj_address = get_pointee_address(self.d)
    if not bool(self.d):
        log.debug('BIGNUM has a Null pointer d')
        return True
    memoryMap = mappings.is_valid_address_value(attr_obj_address)
    # TODO - challenge buffer_copy use,
    contents=(BN_ULONG*self.top).from_buffer_copy(memoryMap.readArray(attr_obj_address, BN_ULONG, self.top))
    mappings.keepRef( contents, model.getSubtype(self.d), attr_obj_address )
    log.debug('contents acquired %d'%ctypes.sizeof(contents))
    return True
Example #25
0
def BIGNUM_loadMembers(self, mappings, maxDepth):
    ''' 
    #self._d = process.readArray(attr_obj_address, ctypes.c_ulong, self.top) 
    ## or        
    #ulong_array= (ctypes.c_ulong * self.top)        
    '''
    if not self.isValid(mappings):
        log.debug('BigNUm tries to load members when its not validated')
        return False
    # Load and memcopy d / BN_ULONG *
    attr_obj_address = get_pointee_address(self.d)
    if not bool(self.d):
        log.debug('BIGNUM has a Null pointer d')
        return True
    memoryMap = mappings.is_valid_address_value(attr_obj_address)
    # TODO - challenge buffer_copy use,
    contents = (BN_ULONG * self.top).from_buffer_copy(
        memoryMap.readArray(attr_obj_address, BN_ULONG, self.top))
    mappings.keepRef(contents, model.getSubtype(self.d), attr_obj_address)
    log.debug('contents acquired %d' % ctypes.sizeof(contents))
    return True
Example #26
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)))
Example #27
0
 def getIV(self, mappings):
     #return pointer2bytes(mappings.getRef(ctypes.Array, get_pointee_address(self.iv)), self.block_size)
     return mappings.array2bytes(
         mappings.getRef(mappings.get_subtype(self.iv),
                         get_pointee_address(self.iv)))
Example #28
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
Example #29
0
 def getCipher(self, mappings):
     cipher = mappings.getRef(Cipher, get_pointee_address(self.cipher))
     return cipher
Example #30
0
def HEAP_get_frontend_chunks(self, mappings):
    """ windows xp ?
        the list of chunks from the frontend are deleted from the segment chunk list.

        Functionnaly, (page 28) LFH_HEAP should be fetched by HEAP_BUCKET calcul

    //position 0x7 in the header denotes
    //whether the chunk was allocated via
    //the front-end or the back-end (non-encoded ;) )
    if(ChunkHeader->UnusedBytes & 0x80)
        RtlpLowFragHeapFree
    else
        BackEndHeapFree

    """
    res = list()
    all_free = list()
    all_committed = list()
    log.debug('HEAP_get_frontend_chunks')
    ptr = self.FrontEndHeap
    addr = utils.get_pointee_address(ptr)
    if self.FrontEndHeapType == 1:  # windows XP per default
        # TODO delete this ptr from the heap-segment entries chunks
        for x in range(128):
            log.debug('finding lookaside %d at @%x' % (x, addr))
            m = mappings.get_mapping_for_address(addr)
            st = m.readStruct(addr, HEAP_LOOKASIDE)
            # load members on self.FrontEndHeap car c'est un void *
            for free in st.iterateList('ListHead'):  # single link list.
                # TODO delete this free from the heap-segment entries chunks
                log.debug('free')
                res.append(free)  # ???
                pass
            addr += ctypes.sizeof(HEAP_LOOKASIDE)
    elif self.FrontEndHeapType == 2:  # win7 per default
        log.debug('finding frontend at @%x' % (addr))
        m = mappings.get_mapping_for_address(addr)
        st = m.readStruct(addr, LFH_HEAP)
        # LFH is a big chunk allocated by the backend allocator, called subsegment
        # but rechopped as small chunks of a heapbin.
        # Active subsegment hold that big chunk.
        #
        #
        # load members on self.FrontEndHeap car c'est un void *
        if not st.loadMembers(mappings, 1):
            log.error('Error on loading frontend')
            raise model.NotValid('Frontend load at @%x is not valid' % (addr))

        # log.debug(st.LocalData[0].toString())
        #
        # 128 HEAP_LOCAL_SEGMENT_INFO
        for sinfo in st.LocalData[0].SegmentInfo:
            # TODO , what about ActiveSubsegment ?
            for items_ptr in sinfo.CachedItems:  # 16 caches items max
                items_addr = utils.get_pointee_address(items_ptr)
                if not bool(items_addr):
                    #log.debug('NULL pointer items')
                    continue
                m = mappings.get_mapping_for_address(items_addr)
                subsegment = m.readStruct(items_addr, HEAP_SUBSEGMENT)
                # log.debug(subsegment)
                # TODO current subsegment.SFreeListEntry is on error at some depth.
                # bad pointer value on the second subsegment
                chunks = subsegment.get_userblocks()
                free = subsegment.get_freeblocks()
                committed = set(chunks) - set(free)
                all_free.extend(free)
                all_committed.extend(committed)
                log.debug(
                    'subseg: 0x%0.8x, commit: %d chunks free: %d chunks' %
                    (items_addr, len(committed), len(free)))
    else:
        # print 'FrontEndHeapType == %d'%(self.FrontEndHeapType)
        #raise StopIteration
        pass
    return all_committed, all_free
Example #31
0
def BIGNUM___str__(self):
    d= get_pointee_address(self.d)
    return ("BN { d=0x%lx, top=%d, dmax=%d, neg=%d, flags=%d }"%
                            (d, self.top, self.dmax, self.neg, self.flags) )
Example #32
0
def BIGNUM_get_d(self):
    return self._mapping_.getRef( model.getSubtype(self.d), get_pointee_address(self.d))
Example #33
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)) )
Example #34
0
 def getName(self, mappings):
     ciphername = mappings.getRef(ctypes.CString,
                                  get_pointee_address(self.name.ptr))
     if ciphername is None:
         raise ValueError('ciphername not in cache')
     return ciphername
Example #35
0
 def getIV(self, mappings):
     #return pointer2bytes(mappings.getRef(ctypes.Array, get_pointee_address(self.iv)), self.block_size) 
     return mappings.array2bytes(mappings.getRef(mappings.get_subtype(self.iv), get_pointee_address(self.iv)) )
Example #36
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
Example #37
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
Example #38
0
 def getCipher(self, mappings):
     cipher = mappings.getRef( Cipher, get_pointee_address(self.cipher))
     return cipher
Example #39
0
def BIGNUM_get_d(self):
    return self._mapping_.getRef(model.getSubtype(self.d),
                                 get_pointee_address(self.d))
Example #40
0
def BIGNUM___str__(self):
    d = get_pointee_address(self.d)
    return ("BN { d=0x%lx, top=%d, dmax=%d, neg=%d, flags=%d }" %
            (d, self.top, self.dmax, self.neg, self.flags))
Example #41
0
 def getName(self, mappings):
     ciphername = mappings.getRef(ctypes.CString, get_pointee_address(self.name.ptr) )
     if ciphername is None:
         raise ValueError('ciphername not in cache')
     return ciphername