def reverse_record(self, _context, _record): if not _record.resolvedPointers: raise ValueError('I should be resolved') _record._dirty = True _record._fields.sort() myfields = [] signature = _record.get_type_signature() pencoder = pattern.PatternEncoder(signature, minGroupSize=2) patterns = pencoder.makePattern() txt = _record.get_type_signature(text=True) p = pattern.findPatternText(txt, 1, 2) log.debug('substruct typeSig: %s' % txt) log.debug('substruct findPatterntext: %s' % p) log.debug('substruct came up with pattern %s' % patterns) # pattern is made on FieldType, # so we need to dequeue _record.fields at the same time to enqueue in # myfields for nb, fieldTypes in patterns: if nb == 1: field = _record._fields.pop(0) myfields.append(field) # single el # log.debug('simple field:%s '%(field) ) elif len(fieldTypes) > 1: # array of subtructure DEBUG XXX TODO log.debug('fieldTypes:%s' % fieldTypes) log.debug('substructure with sig %s', ''.join([ft.sig[0] for ft in fieldTypes])) myelements = [] for i in range(nb): fields = [ _record._fields.pop(0) for i in range(len(fieldTypes)) ] # nb-1 left # otherFields = [ _record.fields.pop(0) for i in range((nb-1)*len(fieldTypesAndSizes)) ] # need global ref to compare substructure signature to # other anonstructure firstField = fieldtypes.RecordField( _record, fields[0].offset, 'unk', 'typename', fields) myelements.append(firstField) array = fieldtypes.ArrayField(myelements) myfields.append(array) # log.debug('array of structure %s'%(array)) # make array of elements obase on same base type elif len(fieldTypes) == 1: log.debug('found array of %s', _record._fields[0].typename.basename) fields = [_record._fields.pop(0) for i in range(nb)] array = fieldtypes.ArrayField(fields) myfields.append(array) # log.debug('array of elements %s'%(array)) else: # TODO DEBUG internal struct raise ValueError('fields patterns len is incorrect %d' % (len(fieldTypes))) log.debug('done with findSubstructure') _record._fields = myfields # print 'final', _record.fields return
def test_makePattern_1(self): sig = ['P4', 'I4', 'I4'] + (['u4', 'z12', 'P4', 'I4'] * 21) + [ 'u172', 'z12' ] + (['I4', 'T8', 'z12', 'I4', 'z12'] * 4) + ['u4', 'z26336'] encoder = pattern.PatternEncoder(sig, 3) #sig_res = 'P4 (I4){2} (u4z12P4I4){21} u172z12 (I4T8z12I4z12){4} u4z26336' sig_res = [(1, 'P4'), (1, 'I4'), (1, 'I4'), (21, ['u4', 'z12', 'P4', 'I4']), (1, 'u172'), (1, 'z12'), (4, ['I4', 'T8', 'z12', 'I4', 'z12']), (1, 'u4'), (1, 'z26336')] self.assertEquals(encoder.makePattern(), sig_res)
def reverse_record(self, _context, _record): """ Aggregate fields of similar type into arrays in the record. """ if _record.get_reverse_level() < 30: raise ValueError('The record reverse level needs to be >30') log.debug('0x%x: %s', _record.address, _record.get_signature_text()) _record._dirty = True _record._fields.sort() myfields = [] signature = _record.get_signature() pencoder = pattern.PatternEncoder(signature, minGroupSize=3) patterns = pencoder.makePattern() #txt = self.getSignature(text=True) #log.warning('signature of len():%d, %s'%(len(txt),txt)) #p = pattern.findPatternText(txt, 2, 3) # log.debug(p) #log.debug('aggregateFields came up with pattern %s'%(patterns)) # pattern is made on FieldType, # so we need to dequeue self.fields at the same time to enqueue in # myfields for nb, fieldTypesAndSizes in patterns: # print 'fieldTypesAndSizes:',fieldTypesAndSizes if nb == 1: fieldType = fieldTypesAndSizes[0] # its a tuple field = _record._fields.pop(0) myfields.append(field) # single el #log.debug('simple field:%s '%(field) ) # array of subtructure DEBUG XXX TODO elif len(fieldTypesAndSizes) > 1: log.debug('substructure with sig %s' % (fieldTypesAndSizes)) myelements = [] for i in range(nb): fields = [ _record._fields.pop(0) for i in range(len(fieldTypesAndSizes)) ] # nb-1 left #otherFields = [ self.fields.pop(0) for i in range((nb-1)*len(fieldTypesAndSizes)) ] # need global ref to compare substructure signature to # other anonstructure firstField = fieldtypes.RecordField( _record, fields[0].offset, 'unk', 'typename', fields) myelements.append(firstField) array = fieldtypes.ArrayField(myelements) myfields.append(array) #log.debug('array of structure %s'%(array)) elif len(fieldTypesAndSizes) == 1: # make array of elements or log.debug("found array of %s", _record._fields[0].typename.basename) fields = [_record._fields.pop(0) for i in range(nb)] array = fieldtypes.ArrayField(fields) myfields.append(array) #log.debug('array of elements %s'%(array)) else: # TODO DEBUG internal struct raise ValueError("fields patterns len is incorrect %d" % len(fieldTypesAndSizes)) log.debug('done with aggregateFields') _record.reset() # _record.add_fields(myfields) _record_type = structure.RecordType('struct_%x' % _record.address, len(_record), myfields) _record.set_record_type(_record_type) _record.set_reverse_level(self._reverse_level) # print 'final', self.fields log.debug('0x%x: %s', _record.address, _record.get_signature_text()) return