Ejemplo n.º 1
0
    def __nextlayer(self):
        if len(self) == 0:
            return self.protocol

        last = self.value[-1].l
        try:
            t, sz = last.nextlayer()
            if t is None and self.leftover is not None:
                return dyn.block(self.leftover)

            if self.leftover is not None:
                self.leftover -= last.size()
                return t

            if t is None and self.leftover is None:
                self.leftover = 0
                return dyn.block(0)

            self.leftover = sz
            return t

        except (AttributeError, NotImplementedError):
            pass

        self.leftover -= last.size()
        return dyn.block(self.leftover)
Ejemplo n.º 2
0
    def __nextlayer(self):
        if len(self) == 0:
            return self.protocol

        last = self.value[-1].l
        try:
            t,sz=last.nextlayer()
            if t is None and self.leftover is not None:
                return dyn.block(self.leftover)

            if self.leftover is not None:
                self.leftover -= last.size()
                return t

            if t is None and self.leftover is None:
                self.leftover = 0
                return dyn.block(0)

            self.leftover = sz
            return t

        except (AttributeError,NotImplementedError):
            pass

        self.leftover -= last.size()
        return dyn.block(self.leftover)
Ejemplo n.º 3
0
class IMAGE_EPILOGUE_DYNAMIC_RELOCATION_HEADER(pstruct.type):
    _fields_ = [
        (uint32, 'EpilogueCount'),
        (uint8, 'EpilogueByteCount'),
        (uint8, 'BranchDescriptorElementSize'),
        (uint16, 'BranchDescriptorCount'),
        (lambda s: dyn.block(s['BranchDescriptorCount'].li.int()),
         'BranchDescriptors'),
        (lambda s: dyn.block(
            ((s['BranchDescriptorCount'].li.int() + 7) & -8) // 8),
         'BranchDescriptorBitmap'),
    ]
Ejemplo n.º 4
0
 def __Info(self):
     res = self['Size'].li.int()
     if res < 4:
         return dyn.block(res - self['Magic'].li.size())
     return ResourceFileType.get(
         self['Magic'].int(),
         blocksize=lambda s, cb=res - self['Magic'].li.size(): cb)
Ejemplo n.º 5
0
    def _object_(self):
        res = self.getparent(HTables)
        index, lengths = len(self.value), res['Rows'].li
        count = lengths[index].int()

        if count:
            cls = self.__class__
            logging.debug(
                "{:s} : {:s} : Loading {:s}({:d}) table with {:d} rows. : {:d} of {:d}"
                .format('.'.join((res.typename(), cls.__name__)),
                        self.instance(), TableType.byvalue(index, 'undefined'),
                        index, count, 1 + len(self.value), self.length))

        rowtype = Table.withdefault(index, type=index)
        rowsize = rowtype.PreCalculateSize(res) if Table.has(index) else 0

        tr, tn = TableRow.__name__, TableType.byvalue(index, None)
        t = dyn.clone(
            TableRow,
            _object_=rowtype,
            _value_=dyn.block(rowsize),
            typename=classmethod(lambda cls: "{:s}({:s})".format(tr, tn)
                                 if tn else tr))

        def Get(self, index):
            if index > 0:
                return self[index - 1]
            raise IndexError(index)

        return dyn.array(t,
                         count,
                         Get=Get,
                         blocksize=(lambda s, cb=rowsize * count: cb))
Ejemplo n.º 6
0
class IMAGE_RESOURCE_DATA_ENTRY(pstruct.type):
    _fields_ = [
        (virtualaddress(lambda s: dyn.block(s.parent['Size'].li.int()), type=dword), 'Data'),
        (dword, 'Size'),
        (dword, 'Codepage'),
        (dword, 'Reserved'),
    ]
Ejemplo n.º 7
0
class WeakExternalAuxiliaryRecord(pstruct.type):
    type = 105
    _fields_ = [
        (dword, 'TagIndex'),
        (dword, 'Characteristics'),
        (dyn.block(10), 'Unused')
    ]
Ejemplo n.º 8
0
class StringTable(pstruct.type):
    _fields_ = [(uint32, 'Size'),
                (lambda s: dyn.block(s['Size'].li.int() - 4), 'Data')]

    def extract(self, offset):
        '''return the string associated with a particular offset'''
        string = self.serialize()[offset:]
        return ptypes.utils.strdup(string, terminator=b'\0')

    def add(self, string):
        '''appends a string to string table, returns offset'''
        res = string.encode(sys.getdefaultencoding()) + b'\0'
        ofs, data = self.size(), self['Data']
        data.length, data.value = data.length + len(
            res), data.serialize() + res
        self['Size'].set(data.size() + self['Size'].size())
        return ofs

    def find(self, string):
        '''returns the offset of the specified string within the string table'''
        res, data = string.encode(
            sys.getdefaultencoding()) + b'\0', self['Data'].serialize()
        index = data.find(res)
        if index == -1:
            raise LookupError(
                "{:s} : Unable to find null-terminated string ({!r}) within string table"
                .format(self.instance(), string))
        return index + self['Size'].size()
Ejemplo n.º 9
0
class CLRAuxiliaryRecord(pstruct.type):
    type = 106
    _fields_ = [
        (byte, 'bAuxType'),
        (byte, 'bReserved'),
        (dword, 'SymbolTableIndex'),
        (dyn.block(12), 'Reserved')
    ]
Ejemplo n.º 10
0
class e_ident(pstruct.type):
    EI_NIDENT = 16

    class EI_CLASS(pint.enum, uchar):
        _values_ = [
            ('ELFCLASSNONE', 0),
            ('ELFCLASS32', 1),
            ('ELFCLASS64', 2),
        ]

    class EI_DATA(pint.enum, uchar):
        # FIXME: switch the byteorder of everything based on this value
        _values_ = [
            ('ELFDATANONE', 0),
            ('ELFDATA2LSB', 1),
            ('ELFDATA2MSB', 2),
        ]

        def order(self):
            res = self.int()
            if res == 1:
                return ptypes.config.byteorder.littleendian
            elif res == 2:
                return ptypes.config.byteorder.bigendian
            return ptypes.config.defaults.integer.order

    class EI_OSABI(pint.enum, uchar):
        _values_ = [
            ('ELFOSABI_SYSV', 0),
            ('ELFOSABI_HPUX', 1),
            ('ELFOSABI_ARM_EABI', 64),
            ('ELFOSABI_STANDALONE', 255),
        ]

    _fields_ = [
        (dyn.block(4), 'EI_MAG'),
        (EI_CLASS, 'EI_CLASS'),
        (EI_DATA, 'EI_DATA'),
        (uchar, 'EI_VERSION'),
        (EI_OSABI, 'EI_OSABI'),
        (uchar, 'EI_ABIVERSION'),
        (dyn.block(EI_NIDENT - 9), 'EI_PAD'),
    ]

    def valid(self):
        return self.initialized and self['EI_MAG'].serialize() == '\x7fELF'
Ejemplo n.º 11
0
class FunctionBoundaryAuxiliaryRecord(pstruct.type):
    type = 101
    _fields_ = [
        (dword, 'Unused[0]'),
        (word, 'Linenumber'),
        (dyn.block(6), 'Unused[1]'),
        (off_t, 'PointerToNextFunction'),
        (word, 'Unused[2]')
    ]
Ejemplo n.º 12
0
class SerBlock(pstruct.type):
    _fields_ = [
        (CInt, 'length'),
        (lambda s: dyn.block(s['length'].li.Get()), 'data'),
    ]

    def summary(self):
        return '{:d} : {:s}'.format(self['length'].Get(),
                                    self['data'].summary())
Ejemplo n.º 13
0
 def __Extra(self):
     fields = [
         'NumberOfSymbols', 'LvaToFirstSymbol', 'NumberOfLinenumbers',
         'LvaToFirstLinenumber', 'RvaToFirstByteOfCode',
         'RvaToLastByteOfCode', 'RvaToFirstByteOfData',
         'RvaToLastByteOfData'
     ]
     bs, res = self.blocksize(), sum(self[fld].li.size() for fld in fields)
     return dyn.block(max(0, bs - res))
Ejemplo n.º 14
0
class IMAGE_DYNAMIC_RELOCATION64(pstruct.type):
    _fields_ = [
        (uint32, 'HeaderSize'),
        (uint32, 'FixupInfoSize'),
        (uint64, 'Symbol'),
        (uint32, 'SymbolGroup'),
        (uint32, 'Flags'),
        (lambda s: dyn.block(s['FixupInfoSize'].li.int()), 'FixupInfo'),
    ]
Ejemplo n.º 15
0
class LTCG_ENTRY(pstruct.type):
    _fields_ = [
        (virtualaddress(lambda self: dyn.block(
            self.getparent(LTCG_ENTRY).li['size'].int()),
                        type=DWORD), 'rva'),
        (DWORD, 'size'),
        (pstr.szstring, 'section'),
        (dyn.padding(4), 'align(section)'),
    ]
Ejemplo n.º 16
0
class IMAGE_DEBUG_DATA_MISC(pstruct.type):
    type = IMAGE_DEBUG_TYPE_.byname('MISC')

    _fields_ = [
        (IMAGE_DEBUG_MISC_, 'DataType'),
        (uint32, 'Length'),
        (uint8, 'Unicode'),
        (dyn.block(3), 'align(Unicode)'),
        (lambda s: dyn.clone(pstr.wstring if s['Unicode'].int() else pstr.string, length=s['Length'].li.int()), 'Data'),
    ]
Ejemplo n.º 17
0
    class _object_(pstruct.type):
        def __data(self):
            cb = self['length'].li.Get()
            return dyn.clone(pstr.wstring, length=cb // 2)

        _fields_ = [
            (CInt, 'length'),
            (__data, 'data'),
            (lambda self: dyn.block(self['length'].li.Get() & 1), r'\0'),
        ]
Ejemplo n.º 18
0
class SectionAuxiliaryRecord(pstruct.type):
    type = 3
    _fields_ = [
        (uint32, 'Length'),
        (uint16, 'NumberOfRelocations'),
        (uint16, 'NumberOfLinenumbers'),
        (dword, 'CheckSum'),
        (word, 'Number'),
        (IMAGE_COMDAT_SELECT, 'Selection'),
        (dyn.block(3), 'Unused')
    ]
Ejemplo n.º 19
0
class ResourceWString(pstruct.type):
    _fields_ = [
        (EncodedInteger, 'Length'),
        (lambda s: dyn.clone(pstr.wstring, length=s['Length'].li.int() // 2),
         'Name'),
        (lambda s: dyn.block(s['Length'].li.int() % 2), 'Padding'),
    ]

    def str(self):
        return self['Name'].str()

    def summary(self):
        return "{:d} {!r}".format(self['Length'].int(), self['Name'].str())
Ejemplo n.º 20
0
    def __Padding(self):
        cb = 0

        ri = self.getparent(ResourceInfo)
        cb += ri['Magic'].li.size()

        rfi = self.getparent(ResourceFileInfo)
        cb += rfi['Manager'].li.size()

        cb += sum(self[n].li.size() for n in ('Version', 'Count', 'Types'))

        top = ri.getoffset() + ri['Size'].li.size()
        bottom = top + cb
        res = (bottom - top) & 7
        return dyn.block((8 - res) if res > 0 else 0)
Ejemplo n.º 21
0
    def __Padding(self):
        cb = 0

        ri = self.getparent(ResourceInfo)
        cb += ri['Magic'].li.size()

        rfi = self.getparent(ResourceFileInfo)
        cb += rfi['Manager'].li.size()

        cb += sum(self[n].li.size() for n in ('Version', 'Count', 'Types'))

        top = ri.getoffset() + ri['Size'].li.size()
        bottom = top + cb
        res = (bottom - top) & 7
        return dyn.block((8 - res) if res > 0 else 0)
Ejemplo n.º 22
0
class IMAGE_DEBUG_DATA_MISC(pstruct.type):
    type = IMAGE_DEBUG_TYPE_.byname('MISC')

    def __Extra(self):
        bs, res = self.blocksize(), sum(
            self[fld].li.size() for fld in
            ['DataType', 'Length', 'Unicode', 'align(Unicode)', 'Data'])
        return dyn.block(max(0, bs - res))

    _fields_ = [
        (IMAGE_DEBUG_MISC_, 'DataType'),
        (DWORD, 'Length'),
        (BYTE, 'Unicode'),
        (dyn.block(3), 'align(Unicode)'),
        (lambda self: dyn.clone(pstr.wstring
                                if self['Unicode'].int() else pstr.string,
                                length=self['Length'].li.int()), 'Data'),
        (__Extra, 'Extra'),
    ]
Ejemplo n.º 23
0
    def _object_(self):
        res = self.getparent(HTables)
        index, lengths = len(self.value), res['Rows'].li
        count = lengths[index].int()

        if count:
            cls = self.__class__
            logging.debug("{:s} : {:s} : Loading {:s}({:d}) table with {:d} rows. : {:d} of {:d}".format('.'.join((res.typename(),cls.__name__)), self.instance(), TableType.byvalue(index, 'undefined'), index, count, 1+len(self.value), self.length))

        rowtype = Table.withdefault(index, type=index)
        rowsize = rowtype.PreCalculateSize(res) if Table.has(index) else 0

        tr, tn = TableRow.__name__, TableType.byvalue(index, None)
        t = dyn.clone(TableRow, _object_=rowtype, _value_=dyn.block(rowsize), typename=classmethod(lambda cls: "{:s}({:s})".format(tr, tn) if tn else tr))

        def Get(self, index):
            if index > 0:
                return self[index - 1]
            raise IndexError(index)
        return dyn.array(t, count, Get=Get, blocksize=(lambda s, cb=rowsize*count: cb))
Ejemplo n.º 24
0
class Certificate(pstruct.type):
    class wRevision(pint.enum, uint16):
        _values_ = [
            ('WIN_CERT_REVISION_1_0', 0x0100),
            ('WIN_CERT_REVISION_2_0', 0x0200),
        ]
    class wCertificateType(pint.enum, uint16):
        _values_ = [
            ('WIN_CERT_TYPE_X509', 0x0001),
            ('WIN_CERT_TYPE_PKCS7_SIGNED_DATA', 0x0002),
            ('WIN_CERT_TYPE_RESERVED_1', 0x0003),
            ('WIN_CERT_TYPE_TS_STACK_SIGNED', 0x0004),
        ]

    _fields_ = [
        (uint32, 'dwLength'),
        (wRevision, 'wRevision'),
        (wCertificateType, 'wCertificateType'),
        (lambda s: dyn.block(s['dwLength'].li.int() - 8), 'bCertificate'),
    ]
Ejemplo n.º 25
0
class Certificate(pstruct.type):
    class wRevision(pint.enum, uint16):
        _values_ = [
            ('WIN_CERT_REVISION_1_0', 0x0100),
            ('WIN_CERT_REVISION_2_0', 0x0200),
        ]

    class wCertificateType(pint.enum, uint16):
        _values_ = [
            ('WIN_CERT_TYPE_X509', 0x0001),
            ('WIN_CERT_TYPE_PKCS7_SIGNED_DATA', 0x0002),
            ('WIN_CERT_TYPE_RESERVED_1', 0x0003),
            ('WIN_CERT_TYPE_TS_STACK_SIGNED', 0x0004),
        ]

    # XXX: The bCertificate field is padded to a qword-boundary. Keep
    #      this in mind if trying to DER decode it.

    _fields_ = [
        (uint32, 'dwLength'),
        (wRevision, 'wRevision'),
        (wCertificateType, 'wCertificateType'),
        (lambda s: dyn.block(s['dwLength'].li.int() - 8), 'bCertificate'),
    ]
Ejemplo n.º 26
0
 def __Data(self):
     res = self.blocksize() - sum(self[n].li.size() for n in ('Manager', 'Reader')) 
     return dyn.clone(self.ResourceData, _value_=dyn.block(res), _object_=self._ResourceData)
Ejemplo n.º 27
0
 class _object_(resources.IMAGE_RESOURCE_DIRECTORY):
     _fields_ = resources.IMAGE_RESOURCE_DIRECTORY._fields_[:]
     _fields_.append(
         (lambda s: dyn.block(s.blocksize() - (s.value[-1].getoffset(
         ) + s.value[-1].blocksize() - s.value[0].getoffset())),
          'ResourceData'))
Ejemplo n.º 28
0
 def __ExportData(self):
     res = sum(self[n].li.size() for _,n in self._fields_[:-1])
     return dyn.block(self.blocksize() - res)
Ejemplo n.º 29
0
 def __Padding(self):
     cb = sum(self[fld].li.size() for _, fld in self._fields_[:-1])
     return dyn.block(self.blocksize() - cb)
Ejemplo n.º 30
0
 def _object_(self):
     # called by 'Address'
     sz = self["Size"].num()
     return dyn.block(sz)
Ejemplo n.º 31
0
 def __Padding(self):
     cb = self['Size'].li.size() + self['Size'].li.int()
     res = cb & 7
     return dyn.block((8 - res) if res > 0 else 0)
Ejemplo n.º 32
0
 def nextlayer(self):
     return dyn.block(self.payload)
Ejemplo n.º 33
0
 def __Magic(self):
     res = self['Size'].li.int()
     return dyn.block(0) if res < 4 else self._Magic
Ejemplo n.º 34
0
 def __ExportData(self):
     res = sum(self[n].li.size() for _,n in self._fields_[:-1])
     return dyn.block(self.blocksize() - res)
Ejemplo n.º 35
0
class IMAGE_DEBUG_DATA_REPRO(pstruct.type):
    type = IMAGE_DEBUG_TYPE_.byname('REPRO')
    _fields_ = [
        (DWORD, 'Size'),
        (lambda self: dyn.block(self['Size'].li.int()), 'Unknown'),
    ]
Ejemplo n.º 36
0
 def __Info(self):
     res = self['Size'].li.int()
     if res < 4:
         return dyn.block(res - self['Magic'].li.size())
     return ResourceFileType.get(self['Magic'].int(), blocksize=lambda s, cb=res - self['Magic'].li.size(): cb)
Ejemplo n.º 37
0
 def __Extra(self):
     bs, res = self.blocksize(), sum(self[fld].li.size()
                                     for fld in ['Signature'])
     return dyn.block(max(0, bs - res))
Ejemplo n.º 38
0
 def Data(self):
     res = self['Size'].li.int()
     if self['Magic'].Valid():
         return self['Info']
     t = dyn.block(res)
     return self.new(t, offset=4, source=ptypes.prov.proxy(self)).li
Ejemplo n.º 39
0
 def _object_(self):
     # called by 'Address'
     res = self['Size'].int()
     return dyn.block(res)
Ejemplo n.º 40
0
class IMAGE_SECTION_HEADER(pstruct.type):
    """PE Executable Section Table Entry"""
    class IMAGE_SCN(pbinary.flags):
        _fields_ = [
            (1, 'MEM_WRITE'),               # 0x80000000
            (1, 'MEM_READ'),                # 0x40000000
            (1, 'MEM_EXECUTE'),             # 0x20000000
            (1, 'MEM_SHARED'),              # 0x10000000
            (1, 'MEM_NOT_PAGED'),           # 0x08000000
            (1, 'MEM_NOT_CACHED'),          # 0x04000000
            (1, 'MEM_DISCARDABLE'),         # 0x02000000
            (1, 'LNK_NRELOC_OVFL'),         # 0x01000000

        #   (1, 'ALIGN_8192BYTES'), # 0x00e00000
        #   (1, 'ALIGN_4096BYTES'), # 0x00d00000
        #   (1, 'ALIGN_2048BYTES'), # 0x00c00000
        #   (1, 'ALIGN_1024BYTES'), # 0x00b00000
        #   (1, 'ALIGN_512BYTES'), # 0x00a00000
        #   (1, 'ALIGN_256BYTES'), # 0x00900000
        #   (1, 'ALIGN_128BYTES'), # 0x00800000
        #   (1, 'ALIGN_64BYTES'), # 0x00700000
        #   (1, 'ALIGN_32BYTES'), # 0x00600000
        #   (1, 'ALIGN_16BYTES'), # 0x00500000
        #   (1, 'ALIGN_8BYTES'), # 0x00400000
        #   (1, 'ALIGN_4BYTES'), # 0x00300000
        #   (1, 'ALIGN_2BYTES'), # 0x00200000
        #   (1, 'ALIGN_1BYTES'), # 0x00100000

            (4, 'ALIGN'),                   # 0x00?00000
            (1, 'MEM_PRELOAD'),             # 0x00080000
            (1, 'MEM_LOCKED'),              # 0x00040000
        #   (1, 'MEM_16BIT'),              # 0x00020000 # ARM
            (1, 'MEM_PURGEABLE'),           # 0x00020000
            (1, 'reserved_16'),

            (1, 'GPREL'),                   # 0x00008000
            (2, 'reserved_14'),
            (1, 'LNK_COMDAT'),              # 0x00001000
            (1, 'LNK_REMOVE'),              # 0x00000800
            (1, 'reserved_11'),
            (1, 'LNK_INFO'),                # 0x00000200
            (1, 'LNK_OTHER'),               # 0x00000100

            (1, 'CNT_UNINITIALIZED_DATA'),  # 0x00000080
            (1, 'CNT_INITIALIZED_DATA'),    # 0x00000040
            (1, 'CNT_CODE'),                # 0x00000020
            (1, 'reserved_4'),
            (1, 'TYPE_NO_PAD'),             # 0x00000008
            (3, 'reserved_0'),
        ]

    # FIXME: we can store a longer than 8 byte Name if we want to implement code that navigates to the string table
    #      apparently executables don't care though...
    _fields_ = [
        (dyn.clone(pstr.string, length=8), 'Name'),
        (uint32, 'VirtualSize'),
        (virtualaddress(lambda s:dyn.block(s.parent.getloadedsize()), type=uint32), 'VirtualAddress'),
        (uint32, 'SizeOfRawData'),
        (fileoffset(lambda s:dyn.block(s.parent.getreadsize()), type=uint32), 'PointerToRawData'),
        (fileoffset(lambda s:dyn.array(relocations.MachineRelocation.lookup(s.getparent(Header).Machine().int()), s.parent['NumberOfRelocations'].li.int()), type=uint32), 'PointerToRelocations'),
        (fileoffset(lambda s:dyn.array(linenumbers.LineNumber, s.parent['NumberOfLinenumbers'].li.int()), type=uint32), 'PointerToLinenumbers'),
        (uint16, 'NumberOfRelocations'),
        (uint16, 'NumberOfLinenumbers'),
        (pbinary.littleendian(IMAGE_SCN), 'Characteristics'),
    ]

    def getreadsize(self):
        portable = self.getparent(SectionTableArray)

        # if it's a portable executable, then apply the alignment
        try:
            nt = portable.p
            alignment = nt['OptionalHeader']['FileAlignment'].int()
            mask = alignment - 1

        # otherwise, there's no alignment necessary
        except KeyError:
            mask = 0

        res = (self['SizeOfRawData'].int() + mask) & ~mask
        return min((self.source.size() - self['PointerToRawData'].int(), res)) if hasattr(self.source, 'size') else res

    def getloadedsize(self):
        # XXX: even though the loadedsize is aligned to SectionAlignment,
        #      the loader doesn't actually map data there and thus the
        #      actual mapped size is rounded to pagesize

        # nt = self.getparent(Header)
        # alignment = nt['OptionalHeader']['SectionAlignment'].int()
        alignment = 0x1000  # pagesize
        mask = alignment - 1
        return (self['VirtualSize'].int() + mask) & ~mask

    def containsaddress(self, address):
        start = self['VirtualAddress'].int()
        return True if (address >= start) and (address < start + self.getloadedsize()) else False

    def containsoffset(self, offset):
        start = self['PointerToRawData'].int()
        return True if (offset >= start) and (offset < start + self.getreadsize()) else False

    def data(self):
        return self['PointerToRawData'].d

    getrelocations = lambda self: self['PointerToRelocations'].d
    getlinenumbers = lambda self: self['NumberOfLinenumbers'].d

    ## offset means file offset
    def getoffsetbyaddress(self, address):
        return address - self['VirtualAddress'].int() + self['PointerToRawData'].int()

    def getaddressbyoffset(self, offset):
        return offset - self['PointerToRawData'].int() + self['VirtualAddress'].int()
Ejemplo n.º 41
0
 def __padding_Tables(self):
     hdr = self.getparent(StreamHdr)
     cb = hdr['Size'].li.int()
     total = sum(self[n].blocksize() for _, n in self._fields_[:-1])
     return dyn.block(max((0, cb-total)))
Ejemplo n.º 42
0
class IMAGE_PROLOGUE_DYNAMIC_RELOCATION_HEADER(pstruct.type):
    _fields_ = [
        (uint8, 'PrologueByteCount'),
        (lambda s: dyn.block(s['PrologueByteCount'].li.int()),
         'PrologueBytes'),
    ]
Ejemplo n.º 43
0
 def _object_(self):
     # called by 'Address'
     res = self['Size'].int()
     return dyn.block(res)
Ejemplo n.º 44
0
 def __StreamData(self):
     cb = self.getparent(IMAGE_DATA_DIRECTORY)['Size'].int()
     total = sum(self[n].li.size() for _, n in self._fields_[:-1])
     res = max((0, cb-total))
     return dyn.block(res)