def guessField(self, vaddr, typename=None, size=-1, padding=False): self._dirty = True offset = vaddr - self._vaddr if offset < 0 or offset > len(self): raise IndexError() if typename is None: typename = FieldType.UNKNOWN # find the maximum size if size == -1: try: nextStruct = itertools.dropwhile(lambda x: (x.offset < offset), sorted(self._fields)).next() nextStructOffset = nextStruct.offset except StopIteration as e: nextStructOffset = len(self) maxFieldSize = nextStructOffset - offset size = maxFieldSize ## field = Field(self, offset, typename, size, padding) if typename == FieldType.UNKNOWN: if not field.decodeType(): return None elif not field.check(): return None if field.size < 0: raise ValueError("error here %s %s" % (field, field.typename)) # field has been typed self._fields.append(field) self._fields.sort() return field
def _fixOverlaps(self): ''' fix overlapping string fields ''' self._dirty = True fields = sorted([f for f in self._fields if f.padding != True ]) # clean paddings to check new fields for f1, f2 in self._getOverlapping(): log.debug('overlappings %s %s' % (f1, f2)) f1_end = f1.offset + len(f1) f2_end = f2.offset + len(f2) if (f1.typename == f2.typename and f2_end == f1_end): # same end, same type self._fields.remove(f2) # use the last one log.debug('Cleaned a field overlaps %s %s' % (f1, f2)) elif f1.isZeroes() and f2.isZeroes(): # aggregate log.debug('aggregate Zeroes') start = min(f1.offset, f2.offset) size = max(f1_end, f2_end) - start try: self._fields.remove(f1) self._fields.remove(f2) self._fields.append( Field(self, start, FieldType.ZEROES, size, False)) except ValueError, e: log.error('please bugfix') else: # TODO pass
def _addField(self, offset, typename, size, padding): if offset < 0 or offset > len(self): raise IndexError() if typename is None: raise ValueError() self._dirty = True # make a field with no autodecode field = Field(self, offset, typename, size, padding) # field has been typed self._fields.append(field) self._fields.sort() return field
def addFields(self, vaddrList, typename, size, padding): vaddrList.sort() if min(vaddrList) < self._vaddr or max( vaddrList) > self._vaddr + len(self): raise IndexError() if typename is None: raise ValueError() self._dirty = True fields = [ Field(self, vaddr - self._vaddr, typename, size, padding) for vaddr in vaddrList ] self._fields.extend(fields) self._fields.sort() return
def _aggregateZeroes(self): ''' sometimes we have a pointer in the middle of a zeroes buffer. we need to aggregate ''' self._dirty = True log.debug('aggregateZeroes: start') myfields = sorted([f for f in self._fields if f.padding != True]) if len(myfields) < 2: log.debug('aggregateZeroes: not so much fields') return newFields = [] newFields.append(myfields[0]) for f in myfields[1:]: last = newFields[-1] if last.isZeroes() and f.isZeroes(): # XXX cant output last, its not part of struct yet, so cant be printed #log.debug('aggregateZeroes: field %s and %s -> %d:%d'%(last,f, last.offset,f.offset+len(f))) try: newFields[-1] = Field(self, last.offset, last.typename, len(last) + len(f), False) except TypeError, e: raise e else: newFields.append(f)
class AnonymousStructInstance(): ''' AnonymousStruct in absolute address space. Comparaison between struct is done is relative addresse space. ''' def __init__(self, context, vaddr, bytes, prefix=None): self._context = context self._mappings = context.mappings self._vaddr = vaddr self._bytes = bytes self.reset() # set fields self.setName(prefix) return def setName(self, name): if name is None: self._name = 'struct_%x' % (self._vaddr) else: self._name = '%s_%x' % (name, self._vaddr) def getName(self): return self._name def setCtype(self, t): self._ctype = t def getCtype(self): if self._ctype is None: raise TypeError('Structure has no type') return self._ctype def reset(self): self._size = len(self._bytes) self._fields = [] self._resolved = False self._pointerResolved = False self._dirty = True return def guessField(self, vaddr, typename=None, size=-1, padding=False): self._dirty = True offset = vaddr - self._vaddr if offset < 0 or offset > len(self): raise IndexError() if typename is None: typename = FieldType.UNKNOWN ## find the maximum size if size == -1: try: nextStruct = itertools.dropwhile(lambda x: (x.offset < offset), sorted(self._fields)).next() nextStructOffset = nextStruct.offset except StopIteration, e: nextStructOffset = len(self) maxFieldSize = nextStructOffset - offset size = maxFieldSize ## field = Field(self, offset, typename, size, padding) if typename == FieldType.UNKNOWN: if not field.decodeType(): return None elif not field.check(): return None if field.size == -1: raise ValueError('error here %s %s' % (field, field.typename)) # field has been typed self._fields.append(field) self._fields.sort() return field