def __padding(self): data = self['e_data'].li sections, segments = data['e_shoff'], data['e_phoff'] position = sum(self[fld].li.size() for fld in ['e_ident', 'e_data', 'e_dataentries']) entry = min([item for item in [sections.int(), sections.int()] if item > position]) return ptype.clone(ptype.block, length=max(0, entry - position))
def __members(self): res, t = self['armag'].li, self._members if isinstance(self.source, ptypes.prov.bounded): expected = self.source.size() - res.size() return ptype.clone(t, blocksize=lambda _, cb=max(0, expected): cb) cls = self.__class__ logging.warning("{:s} : Unable to determine number of members for {!s} when reading from an unbounded source.".format(self.instance(), t)) return t
def __e_data(self): e_ident = self['e_ident'].li # Figure out the EI_CLASS to determine the Ehdr size ei_class = e_ident['EI_CLASS'] if ei_class['ELFCLASS32']: t = header.Elf32_Ehdr elif ei_class['ELFCLASS64']: t = header.Elf64_Ehdr else: raise NotImplementedError(ei_class) # Now we can clone it using the byteorder from EI_DATA ei_data = e_ident['EI_DATA'] return ptype.clone(t, recurse={'byteorder': ei_data.order()})
def __e_sectionhdrentries(self): data = self['e_data'].li sections, segments = data['e_shoff'], data['e_phoff'] if isinstance(self.source, ptypes.provider.memorybase): return ptype.undefined e_ident = self['e_ident'].li ei_class = e_ident['EI_CLASS'] if ei_class['ELFCLASS32']: t = section.Elf32_Shdr elif ei_class['ELFCLASS64']: t = section.Elf64_Shdr else: raise NotImplementedError(ei_class) # FIXME: this needs to be properly calculated to ensure it's actually next count = data['e_shnum'].int() if segments.int() < sections.int() else 0 return ptype.clone(header.ShdrEntries, _object_=t, length=count)
def __b(self): return ptype.clone(pint.int_t, length=self['a'].li.int())
def protocol(layer): return ptype.clone(layers, protocol=layer)
def _object_(self): length = 0 if len(self.value) == 0 else (self.value[-1].length+1)%4 return ptype.clone(pint.uint_t,length=length)
def test_array_set_initialized_instance(): b = ptype.clone(parray.type,_object_=pint.uint8_t,length=4) a = parray.type(_object_=pint.uint8_t,length=4).a a.set(tuple(pint.uint32_t().set(0x40) for x in six.moves.range(4))) if sum(x.int() for x in a) == 256: raise Success
def test_array_set_initialized_container(): b = ptype.clone(parray.type,_object_=pint.uint8_t,length=4) a = parray.type(_object_=pint.uint8_t,length=4).a a.set((b,)*4) if sum(x.size() for x in a) == 16: raise Success
def _object_(self, items=sorted): item = items[len(self.value)] if isinstance(item, segment.ElfXX_Phdr): return ptype.clone(segment_t, __segment__=item) return ptype.clone(section_t, __section__=item)
def test_array_set_initialized_instance(): b = ptype.clone(parray.type,_object_=pint.uint8_t,length=4) a = parray.type(_object_=pint.uint8_t,length=4).a a.set(tuple(pint.uint32_t().set(0x40) for x in range(4))) if sum(x.int() for x in a) == 256: raise Success
class st1(pstruct.type): _fields_ = [ (pint.int8_t, 'a'), (lambda s: ptype.clone(pint.int_t, length=s['a'].li.int()), 'b') ]
def __e_dataentries(self): data = self['e_data'].li if isinstance(self.source, ptypes.provider.memorybase): return ptype.clone(parray.type, _object_=segment.MemorySegmentData, length=0) # If we're using a file source, then we'll need to include both sections # _and_ segments. We'll also create some lookup dicts so that we can # identify which type is at a particular offset. This way we can give # the sections priority since we're dealing with files. sections, segments = data['e_shoff'].d, data['e_phoff'].d segmentlist = [phdr for _, phdr in segments.li.sorted()] sectionlist = [shdr for _, shdr in sections.li.sorted()] segmentlookup = {phdr['p_offset'].int() : phdr for phdr in segmentlist} segmentlookup.update({phdr['p_offset'].int() + phdr.getreadsize() : phdr for phdr in segmentlist if phdr.getreadsize() > 0}) sectionlookup = {shdr['sh_offset'].int() : shdr for shdr in sectionlist} sectionlookup.update({shdr['sh_offset'].int() + shdr.getreadsize() : shdr for shdr in sectionlist if shdr.getreadsize() > 0}) # Now we need to sort both of them into a single list so we can figure # out the layout of this executable. To do this, we're just going to # create a list of the offset of each boundary. This way we can use # our lookup tables to figure out which type is the right one. layout = [] for phdr in segmentlist: offset = phdr['p_offset'].int() bisect.insort(layout, offset) bisect.insort(layout, offset + phdr.getreadsize()) for shdr in sectionlist: offset = shdr['sh_offset'].int() bisect.insort(layout, offset) bisect.insort(layout, offset + shdr.getreadsize()) # Our layout contains the boundaries of all of our sections, so now # we need to walk our layout and determine whether there's a section # or a segment at that particular address. # FIXME: we need to filter out segments here if we found a section that # is contained within it. sorted, used = [], {item for item in []} for boundary, _ in itertools.groupby(layout): item = sectionlookup.get(boundary, segmentlookup.get(boundary, None)) if item is None or item in used: continue sorted.append(item) used.add(item) # Figure out which types we need to use depending on the source if isinstance(self.source, ptypes.provider.memorybase): section_t, segment_t = section.SectionData, segment.MemorySegmentData else: section_t, segment_t = section.SectionData, segment.FileSegmentData # Everything has been sorted, so now we can construct our array and # align it properly to load as many contiguous pieces as possible. def _object_(self, items=sorted): item = items[len(self.value)] if isinstance(item, segment.ElfXX_Phdr): return ptype.clone(segment_t, __segment__=item) return ptype.clone(section_t, __section__=item) # Finally we can construct our array composed of the proper types return ptype.clone(parray.type, _object_=_object_, length=len(sorted))