def test_subtype(self):
        start = self.offsets['start_list'][0]
        _record = structure.AnonymousRecord(self.memory_handler, start, 40)
        word_size = self._target.get_word_size()

        f1 = fieldtypes.Field('f1', 0 * word_size, fieldtypes.ZEROES,
                              word_size, False)
        f4 = fieldtypes.Field('f2', 3 * word_size, fieldtypes.ZEROES,
                              word_size, False)
        # offset in the substruct
        fs2 = fieldtypes.PointerField('Back', 0, word_size)
        fs2.value = start
        fs3 = fieldtypes.PointerField('Next', 1 * word_size, word_size)
        fs3.value = start
        # the new field sub record
        new_field = fieldtypes.RecordField(_record, 1 * word_size, 'list',
                                           'LIST_ENTRY', [fs2, fs3])
        # fieldtypes.FieldType.makeStructField(_record, 1*word_size, 'LIST_ENTRY', [fs2, fs3], 'list')
        # add them
        fields = [f1, new_field, f4]
        #_record.add_fields(fields)
        _record_type = structure.RecordType('struct_text', 40, fields)
        _record.set_record_type(_record_type)
        self.assertEqual(len(_record), 40)
        f1, f2, f3 = _record.get_fields()
        self.assertEqual(len(f1), word_size)
        self.assertEqual(len(f2), word_size * 2)
        self.assertEqual(len(f3), word_size)

        self.assertEqual(f2.name, 'list')
        self.assertIsInstance(f2.field_type, fieldtypes.FieldTypeStruct)
        self.assertEqual(f2.field_type.name, 'LIST_ENTRY')

        print _record.to_string()
예제 #2
0
    def test_save_record_type(self):
        process_context = self.memory_handler.get_reverse_context()

        _record = structure.AnonymousRecord(self.memory_handler, 0xdeadbeef,
                                            40)
        word_size = self.my_target.get_word_size()

        f1 = fieldtypes.Field('f1', 0 * word_size, fieldtypes.ZEROES,
                              word_size, False)
        f2 = fieldtypes.Field('f2', 1 * word_size, fieldtypes.ZEROES,
                              word_size, False)
        fields = [f1, f2]
        _record_type = fieldtypes.RecordType('struct_test', 2 * word_size,
                                             fields)
        _record.set_record_type(_record_type)
        # same fields
        self.assertEqual(f1, _record.get_fields()[0].type)
        self.assertEqual(f1, _record.get_field('f1').type)
        # Check get_fields return a new list of fields
        x = _record.get_fields()
        self.assertEqual(x, _record.get_fields())
        x.pop(0)
        self.assertNotEqual(x, _record.get_fields())

        process_context.add_reversed_type(_record_type, [1, 2, 3])

        r_types = list(process_context.list_reversed_types())
        self.assertEqual(r_types[0].type_name, 'struct_test')
예제 #3
0
 def _aligned_gaps(self, _record, endoffset, nextoffset, gaps):
     """ if nextoffset is aligned
                 add a gap to gaps, or
             if nextoffset is not aligned
                 add (padding + gap) to gaps
              """
     if nextoffset % self._word_size == 0:
         gap = fieldtypes.Field('gap_%d' % nextoffset, nextoffset,
                                fieldtypes.UNKNOWN, endoffset - nextoffset,
                                False)
         log.debug('_make_gaps: adding field at offset %d:%d', gap.offset,
                   gap.offset + len(gap))
         gaps.append(gap)
     else:
         # we need a field of endoffset - nextoffset bytes.
         # unaligned field should be splitted
         size = endoffset - nextoffset
         if size < self._word_size:
             s1 = size
         else:
             s1 = size - size % self._word_size
         gap1 = fieldtypes.Field('gap_%d' % nextoffset, nextoffset,
                                 fieldtypes.UNKNOWN, s1, True)
         log.debug('_make_gaps: Unaligned field at offset %d:%d',
                   gap1.offset, gap1.offset + len(gap1))
         gaps.append(gap1)
         if nextoffset + s1 < endoffset:
             gap2 = fieldtypes.Field('gap_%d' % (nextoffset + s1),
                                     nextoffset + s1, fieldtypes.UNKNOWN,
                                     endoffset - nextoffset - s1, True)
             log.debug('_make_gaps: adding field at offset %d:%d',
                       gap2.offset, gap2.offset + len(gap2))
             gaps.append(gap2)
     return
예제 #4
0
 def make_fields(self, _record, offset, size):
     # vaddr and offset should be aligned
     assert (offset % self._word_size == 0)
     # log.debug('checking String')
     fields = []
     _bytes = _record.bytes
     while size >= self._word_size:
         # print 're_string.find_ascii(bytes, %d, %d)'%(offset,size)
         index, ssize = re_string.find_ascii(_bytes, offset, size)
         if index == 0:
             _offset = offset + index
             if (ssize <
                     size) and _bytes[offset + index +
                                      ssize] == '\x00':  # space for a \x00
                 ssize += 1
                 f = fieldtypes.Field('strnull_%d' % _offset, _offset,
                                      fieldtypes.STRINGNULL, ssize, False)
             else:
                 f = fieldtypes.Field('str_%d' % _offset, _offset,
                                      fieldtypes.STRING, ssize, False)
             # print repr(structure.bytes[f.offset:f.offset+f.size])
             fields.append(f)
             size -= ssize  # reduce unknown field
             offset += ssize
             if ssize % self._word_size:
                 rest = self._word_size - ssize % self._word_size
                 size -= rest  # goto next aligned
                 offset += rest
         else:
             size -= self._word_size  # reduce unkown field
             offset += self._word_size
     # look in head
     return fields
    def test_gaps(self):
        g1 = fieldtypes.Field('gap_0', 0, fieldtypes.UNKNOWN, 1, False)
        self.assertEqual(len(g1), 1)
        self.assertTrue(g1.is_gap())
        print g1.to_string('\x00\x00\x00\x00')
        self.assertIn('ctypes.c_ubyte*1 )', g1.to_string('\x00\x00\x00\x00'))

        g2 = fieldtypes.Field('gap_0', 0, fieldtypes.UNKNOWN, 2, False)
        self.assertEqual(len(g2), 2)
        self.assertIn('ctypes.c_ubyte*2 )', g2.to_string('\x00\x00\x00\x00'))
    def test_equals(self):
        start = self.offsets['start_list'][0]
        _record = structure.AnonymousRecord(self.memory_handler, start, 40)
        word_size = self._target.get_word_size()

        f1 = fieldtypes.Field('f1', 0 * word_size, fieldtypes.ZEROES,
                              word_size, False)
        f2 = fieldtypes.Field('f2', 1 * word_size, fieldtypes.ZEROES,
                              word_size, False)
        fields = [f1, f2]
        _record_type = structure.RecordType('struct_text', 2 * word_size,
                                            fields)
        _record.set_record_type(_record_type)

        self.assertEqual(f1, _record.get_fields()[0])
        self.assertEqual(f1, _record.get_field('f1'))
예제 #7
0
 def _make_gaps(self, _record, fields):
     fields.sort()
     gaps = []
     nextoffset = 0
     for i, f in enumerate(fields):
         if f.offset > nextoffset:  # add temp padding field
             self._aligned_gaps(_record, f.offset, nextoffset, gaps)
         elif f.offset < nextoffset:
             log.debug(_record)
             log.debug(f)
             log.debug('%s < %s ' % (f.offset, nextoffset))
             log.debug(fields[i + 1])
             log.error("need to TU the fields gap with utf8 text")
             assert False  # f.offset < nextoffset # No overlaps authorised
             # fields.remove(f)
         # do next field
         nextoffset = f.offset + len(f)
     # conclude on QUEUE insertion
     lastfield_size = len(_record) - nextoffset
     if lastfield_size > 0:
         if lastfield_size < self._word_size:
             gap = fieldtypes.Field('gap_%d' % nextoffset, nextoffset,
                                    fieldtypes.UNKNOWN, lastfield_size,
                                    True)
             log.debug('_make_gaps: adding last field at offset %d:%d',
                       gap.offset, gap.offset + len(gap))
             gaps.append(gap)
         else:
             self._aligned_gaps(_record, len(_record), nextoffset, gaps)
     return gaps
예제 #8
0
    def test_get_fields(self):
        _record = structure.AnonymousRecord(self.memory_handler, 0xdeadbeef, 40)
        word_size = self.target.get_word_size()

        f1 = fieldtypes.Field('f1', 0*word_size, fieldtypes.ZEROES, word_size, False)
        f2 = fieldtypes.Field('f2', 1*word_size, fieldtypes.ZEROES, word_size, False)
        fields = [f1, f2]
        _record_type = fieldtypes.RecordType('struct_test', 2 * word_size, fields)
        _record.set_record_type(_record_type)
        # same fields
        self.assertEqual(f1, _record.get_fields()[0].type)
        self.assertEqual(f1, _record.get_field('f1').type)
        # get_fields return a new list of fields
        x = _record.get_fields()
        self.assertEqual(x, _record.get_fields())
        x.pop(0)
        self.assertNotEqual(x, _record.get_fields())
예제 #9
0
 def check_small_integers(self, my_bytes, offset, endianess='<'):
     """ check for small value in signed and unsigned forms """
     data = my_bytes[offset:offset + self._word_size]
     val = self._target.get_target_ctypes_utils().unpackWord(
         data, endianess)
     # print endianess, val
     if val < 0xffff:
         field = fieldtypes.Field('small_int_%d' % offset, offset,
                                  fieldtypes.SMALLINT, self._word_size,
                                  False)
         # FIXME
         field.value = val
         field.endianess = endianess
         return field
     # check signed int
     elif (2**(self._word_size * 8) - 0xffff) < val:
         _name = 'small_signed_int_%d' % offset
         field = fieldtypes.Field(_name, offset, fieldtypes.SIGNED_SMALLINT,
                                  self._word_size, False)
         # FIXME
         field.value = val
         field.endianess = endianess
         return field
     return None
예제 #10
0
 def make_fields(self, _record, offset, size):
     assert (offset % self._word_size == 0
             )  # vaddr and offset should be aligned
     # log.debug('checking String')
     fields = []
     _bytes = _record.bytes
     while size > self._word_size:
         # print 're_string.rfind_utf16(bytes, %d, %d)'%(offset,size)
         # we force aligned results only. otherwise er have overlaps
         index = re_string.rfind_utf16(_bytes, offset, size, False,
                                       self._word_size)
         if index > -1:
             _offset = offset + index
             f = fieldtypes.Field('utf16_%d' % _offset, _offset,
                                  fieldtypes.STRING16, size - index, False)
             # print repr(structure.bytes[f.offset:f.offset+f.size])
             fields.append(f)
             size = index  # reduce unknown field in prefix
         else:
             size -= self._word_size  # reduce unkown field
     # look in head
     return fields
예제 #11
0
    def _analyze(self, _record):
        slen = len(_record)
        offset = 0
        # call on analyzers
        fields = []
        nb = -1
        gaps = [
            fieldtypes.Field('unknown_0', 0, fieldtypes.UNKNOWN, len(_record),
                             False)
        ]

        _record.set_reverse_level(10)

        # find zeroes
        # find strings
        # find smallints
        # find pointers
        for analyser in [
                self.zero_a, self.utf16_a, self.ascii_a, self.int_a, self.ptr_a
        ]:
            log.debug("analyzing with %s", analyser)
            for field in gaps:
                if field.padding:
                    fields.append(field)
                    continue
                log.debug('Using %s on %d:%d', analyser.__class__.__name__,
                          field.offset, field.offset + len(field))
                new_fields = analyser.make_fields(_record, field.offset,
                                                  len(field))
                fields.extend(new_fields)
                for f1 in new_fields:
                    log.debug('new_field %s', f1)
                # print fields
            if len(fields) != nb:  # no change in fields, keep gaps
                nb = len(fields)
                gaps = self._make_gaps(_record, fields)
            if len(gaps) == 0:
                return fields, gaps
        return fields, gaps