Exemple #1
0
class IMAGE_RESOURCE_DIRECTORY(pstruct.type):
    _fields_ = [
        (dword, 'Characteristics'),
        (TimeDateStamp, 'TimeDateStamp'),
        (word, 'MajorVersion'),
        (word, 'MinorVersion'),
        (word, 'NumberOfNamedEntries'),
        (word, 'NumberOfIdEntries'),
        (lambda self: dyn.clone(IMAGE_RESOURCE_DIRECTORY_NAME, length=self['NumberOfNamedEntries'].li.int()), 'Names'),
        (lambda self: dyn.clone(IMAGE_RESOURCE_DIRECTORY_ID, length=self['NumberOfIdEntries'].li.int()), 'Ids'),
    ]

    def iterate(self):
        names = (item.Name() for item in self['Names'])
        identifiers = (item.Name() for item in self['Ids'])
        return itertools.chain(names, identifiers)
    def list(self):
        return [item for item in self.iterate()]
    def entry(self, name):
        iterable = (item['Entry'].d for item in itertools.chain(iter(self['Names']), iter(self['Ids'])) if name == item.Name())
        return next(iterable, None)

    # aliases
    Iterate = iterate
    List = list
    Entry = entry
Exemple #2
0
class IMAGE_COR20_HEADER(pstruct.type):
    def blocksize(self):
        return self['cb'].li.int()

    _fields_ = [
        (pint.uint32_t, 'cb'),
        (pint.uint16_t, 'MajorRuntimeVersion'),
        (pint.uint16_t, 'MinorRuntimeVersion'),
        (dyn.clone(IMAGE_DATA_DIRECTORY, _object_=MetaDataRoot), 'MetaData'),
        (CORIMAGE_FLAGS_, 'Flags'),
        (pint.uint32_t, 'EntryPoint'),
        (dyn.clone(IMAGE_DATA_DIRECTORY,
                   _object_=lambda s: dyn.blockarray(
                       ResourceInfo,
                       s.getparent(IMAGE_DATA_DIRECTORY)['Size'].li.int())),
         'Resources'),
        (IMAGE_DATA_DIRECTORY, 'StrongNameSignature'),
        (IMAGE_DATA_DIRECTORY, 'CodeManagerTable'),
        (dyn.clone(IMAGE_DATA_DIRECTORY,
                   _object_=lambda s: dyn.blockarray(
                       VtableFixup,
                       s.getparent(IMAGE_DATA_DIRECTORY)['Size'].li.int())),
         'VTableFixups'),
        (IMAGE_DATA_DIRECTORY, 'ExportAddressTableJumps'),
        (IMAGE_DATA_DIRECTORY, 'ManagedNativeHeader'),
    ]
Exemple #3
0
 def __e_data(self):
     e_ident = self['e_ident'].li
     type = e_ident['EI_CLASS'].int()
     order = e_ident['EI_DATA'].order()
     if type == 1:
         return dyn.clone(header.Elf32_Ehdr, recurse=dict(byteorder=order))
     elif type == 2:
         return dyn.clone(header.Elf64_Ehdr, recurse=dict(byteorder=order))
     raise ValueError(type)
Exemple #4
0
 def __e_data(self):
     e_ident = self['e_ident'].li
     type = e_ident['EI_CLASS'].int()
     order = e_ident['EI_DATA'].order()
     if type == 1:
         return dyn.clone(header.Elf32_Ehdr, recurse=dict(byteorder=order))
     elif type == 2:
         return dyn.clone(header.Elf64_Ehdr, recurse=dict(byteorder=order))
     raise ValueError(type)
Exemple #5
0
    def __Index(self):
        htables = self.getparent(HTables)

        # get indices of all tables that tag can point into
        indices = self.Tables()

        # figure out the maximum number of rows for the tables specified by self.Tag
        res = htables['Rows'].li
        count = max(res[index].int() for index in indices)

        # return a uint16_t if the tagged index is able to store the maximum number of rows otherwise use a uint32_t
        return dyn.clone(pint.uint_t, length=1) if count < 2**(
            16 - self.Tag.width) else dyn.clone(pint.uint_t, length=3)
Exemple #6
0
 class record0085(pstruct.type):
     _fields_ = [
         (pint.uint16_t, 'unknown'),
         (pint.uint32_t, 'skipped'),
         (pint.uint16_t, 'sheetname_length'),
         (lambda s: dyn.clone(pstr.wstring, length=s['sheetname_length'].li.int()), 'sheetname'),
     ]
Exemple #7
0
 def _object_(self):
     res = self.getparent(StreamHdr)
     cb = res['Size'].int()
     t = Stream.withdefault(res['Name'].str(), blocksize=lambda s, cb=cb: cb)
     if issubclass(t, parray.block):
         return dyn.clone(t, blocksize=lambda s, cb=cb: cb)
     return t
Exemple #8
0
class IMAGE_RESOURCE_DIRECTORY_STRING(pstruct.type):
    _fields_ = [
        (word, 'Length'),
        (lambda s: dyn.clone(pstr.wstring, length=s['Length'].li.int()), 'String')
    ]
    def str(self):
        return self['String'].str()
Exemple #9
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))
Exemple #10
0
class IMAGE_BASERELOC_DIRECTORY_ENTRY(pstruct.type):
    _fields_ = [
        (uint32,
         'Page RVA'),  # FIXME: this can be a virtualaddress(...) to the page
        (uint32, 'Size'),
        (lambda s: dyn.clone(BaseRelocationBlock,
                             length=s['Size'].li.int() - 8), 'Relocations'),
        #        (lambda s: dyn.clone(pbinary.blockarray,_object_=BaseRelocationEntry, blockbits=lambda _:(s['Size'].li.int()-8)*8), 'Relocations')
        #        (lambda s: dyn.clone(BaseRelocationArray, blocksize=lambda _:s['Size'].li.int()-8), 'Relocations')
    ]

    def extract(self):
        '''Return a list of tuples containing the relocation type and offset contained within this entry.'''
        block = self['Relocations'].serialize()
        relocations = array.array(
            'I' if len(array.array('I', 4 * b'\0')) > 1 else 'H', block)
        return [((item & 0xf000) // 0x1000, item & 0x0fff)
                for item in relocations]

    def getrelocations(self, section):
        pageoffset = self['Page RVA'].int() - section['VirtualAddress'].int()
        if not (pageoffset >= 0 and pageoffset < section.getloadedsize()):
            raise AssertionError(
                "Page Offset in RVA outside bounds of section : not(0 <= {:#x} < {:#x}) : Page RVA {:#x}, VA = {:#x}, Section = {:s}"
                .format(pageoffset, section.getloadedsize(),
                        self['Page RVA'].int(),
                        section['VirtualAddress'].int(),
                        section['Name'].str()))

        for type, offset in self.extract():
            if type == 0:
                continue
            yield type, pageoffset + offset
        return
Exemple #11
0
 def _object_(self):
     res = self.getparent(StreamHdr)
     cb = res['Size'].int()
     t = Stream.withdefault(res['Name'].str(),
                            blocksize=lambda s, cb=cb: cb)
     if issubclass(t, parray.block):
         return dyn.clone(t, blocksize=lambda s, cb=cb: cb)
     return t
Exemple #12
0
 def __Children(self):
     bs = self['wLength'].li.num() - self.blocksize()
     assert bs >= 0,bs
     class Member(pstruct.type):
         _fields_ = [
             (dyn.align(4), 'Padding'),
             (self.Child(), 'Child'),
         ]
     return dyn.clone(parray.block, _object_=Member, blocksize=lambda s:bs)
Exemple #13
0
class FileAuxiliaryRecord(pstruct.type):
    type = 103
    _fields_ = [
        #(dyn.block(18), 'File Name')
        (dyn.clone(pstr.string, length=18), 'File Name')
    ]

    def summary(self):
        return ptypes.utils.strdup(self['File Name'].str(), terminator='\0')
Exemple #14
0
 def __IAT(self):
     res = IMAGE_IMPORT_ADDRESS_TABLE64 if self.getparent(
         Header)['OptionalHeader'].is64() else IMAGE_IMPORT_ADDRESS_TABLE
     if hasattr(ptypes.provider,
                'Ida') and self.source is ptypes.provider.Ida:
         entry = self.getparent(IMAGE_DELAYLOAD_DIRECTORY_ENTRY)
         count = entry['DINT'].li.d.l
         return dyn.clone(res, length=len(count))
     return res
Exemple #15
0
class IMAGE_DEBUG_DATA_CODEVIEW(pstruct.type):
    type = IMAGE_DEBUG_TYPE_.byname('CODEVIEW')
    def __Info(self):
        res = self['Signature'].li.serialize()
        return CodeViewInfo.lookup(res)

    _fields_ = [
        (dyn.clone(pstr.string, length=4), 'Signature'),
        (__Info, 'Info'),
    ]
Exemple #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'),
    ]
Exemple #17
0
    def __Index(self):
        htables = self.getparent(HTables)

        # get indices of all tables that tag can point into
        indices = self.Tables()

        # figure out the maximum number of rows for the tables specified by self.Tag
        res = htables['Rows'].li
        count = max(res[index].int() for index in indices)

        # return a uint16_t if the tagged index is able to store the maximum number of rows otherwise use a uint32_t
        return dyn.clone(pint.uint_t, length=1) if count < 2**(16 - self.Tag.width) else dyn.clone(pint.uint_t, length=3)
Exemple #18
0
class ResourceString(pstruct.type):
    _fields_ = [
        (EncodedInteger, 'Length'),
        (lambda s: dyn.clone(pstr.string, length=s['Length'].li.int()),
         'Name'),
    ]

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

    def summary(self):
        return "{:d} {!r}".format(self['Length'].int(), self['Name'].str())
Exemple #19
0
class SerString(pstruct.type):
    _fields_ = [
        (CInt, 'length'),
        (lambda s: dyn.clone(pstr.string, length=s['length'].li.Get()),
         'string'),
    ]

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

    def summary(self):
        return '{:d} : {!r}'.format(self['length'].Get(), self['string'].str())
Exemple #20
0
class MetaDataRoot(pstruct.type):
    class _Signature(pint.uint32_t):
        def properties(self):
            res = super(MetaDataRoot._Signature, self).properties()
            res['valid'] = self.valid()
            return res

        def valid(self):
            return self.int() == 0x424a5342

    class _StreamHeaders(parray.type):
        _object_ = StreamHdr

        def Get(self, name):
            res = next((stream for stream in self if stream.Name() == name),
                       None)
            if res is None:
                raise NameError(name)
            return res

    def __StreamHeaders(self):
        res = self['Streams'].li.int()
        return dyn.clone(self._StreamHeaders, length=res)

    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)

    @pbinary.littleendian
    class StorageFlags(pbinary.flags):
        _fields_ = [
            (15, 'Reserved'),
            (1, 'ExtraData'),
        ]

    _fields_ = [
        (_Signature, 'Signature'),
        (pint.uint16_t, 'MajorVersion'),
        (pint.uint16_t, 'MinorVersion'),
        (pint.uint32_t, 'Reserved'),
        (pint.uint32_t, 'Length'),
        (lambda s: dyn.clone(pstr.string, length=s['Length'].li.int()),
         'Version'),
        (dyn.align(4), 'aligned(Version)'),
        (StorageFlags, 'Flags'),
        (pint.uint16_t, 'Streams'),
        (__StreamHeaders, 'StreamHeaders'),
        (__StreamData, 'StreamData'),
    ]
Exemple #21
0
    def __Children(self):
        fields = self._fields_[:-1]
        length, cb = self['wLength'].li.int(), sum(self[name].li.size() for _, name in fields)

        if cb > length:
            raise AssertionError("Invalid block size returned for child: {:d}".format(bs))

        ct = self.__ChildType()
        class Member(pstruct.type):
            _fields_ = [
                (dyn.align(4), 'Padding'),
                (ct, 'Child'),
            ]
        return dyn.clone(parray.block, _object_=Member, blocksize=lambda s, bs=length-cb:bs)
Exemple #22
0
    def __Children(self):
        fields = self._fields_[:-1]
        length, cb = self['wLength'].li.int(), sum(self[name].li.size() for _, name in fields)

        if cb > length:
            raise AssertionError("Invalid block size returned for child: {:d}".format(bs))

        ct = self.__ChildType()
        class Member(pstruct.type):
            _fields_ = [
                (dyn.align(4), 'Padding'),
                (ct, 'Child'),
            ]
        return dyn.clone(parray.block, _object_=Member, blocksize=lambda s, bs=length-cb:bs)
Exemple #23
0
    def __Children(self):
        fields = ['wLength', 'wValueLength', 'wType', 'szKey', 'Alignment', 'Value']
        length, cb = self['wLength'].li.int(), sum(self[fld].li.size() for fld in fields)

        if cb > length:
            raise AssertionError("Invalid block size returned for child: {:d}".format(bs))

        ct = self.__ChildType()
        class Member(pstruct.type):
            _fields_ = [
                (dyn.align(4), 'Alignment'),
                (ct, 'Child'),
            ]
        return dyn.clone(parray.block, _object_=Member, blocksize=lambda self, bs=length - cb: bs)
Exemple #24
0
class IMAGE_RESOURCE_DIRECTORY(pstruct.type):
    _fields_ = [
        (dword, 'Characteristics'),
        (TimeDateStamp, 'TimeDateStamp'),
        (word, 'MajorVersion'),
        (word, 'MinorVersion'),
        (word, 'NumberOfNames'),
        (word, 'NumberOfIds'),
        (lambda s: dyn.clone(IMAGE_RESOURCE_DIRECTORY_NAME, length=s['NumberOfNames'].li.int()), 'Names'),
        (lambda s: dyn.clone(IMAGE_RESOURCE_DIRECTORY_ID, length=s['NumberOfIds'].li.int()), 'Ids'),
    ]

    def Iterate(self):
        return itertools.chain((n.Name() for n in self['Names']), (n.Name() for n in self['Ids']))
    def List(self):
        return list(self.Iterate())
    def Entry(self, name):
        iterable = (n['Entry'].d for n in itertools.chain(iter(self['Names']), iter(self['Ids'])) if name == n.Name())
        return next(iterable, None)

    # aliases
    iterate = Iterate
    list = List
    entry = Entry
Exemple #25
0
class IMAGE_DEBUG_DATA_CODEVIEW(pstruct.type):
    type = IMAGE_DEBUG_TYPE_.byname('CODEVIEW')

    def __Info(self):
        res = self['Signature'].li.serialize()
        return CodeViewInfo.lookup(res)

    def __Extra(self):
        bs, res = self.blocksize(), sum(self[fld].li.size()
                                        for fld in ['Signature', 'Info'])
        return dyn.block(max(0, bs - res))

    _fields_ = [
        (dyn.clone(pstr.string, length=4), 'Signature'),
        (__Info, 'Info'),
        (__Extra, 'Extra'),
    ]
Exemple #26
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'),
    ]
Exemple #27
0
class TryBlockMapEntry(pstruct.type):
    class _pHandlerArray(parray.type):
        _object_ = HandlerType

        def details(self):
            items = []
            for item in self:
                position = ptypes.utils.repr_position(item.getposition())
                description = ptypes.utils.repr_instance(
                    item.classname(), item.name())

                res = item['adjectives']
                iterable = (fld if item[fld] in {1} else "{:s}={:#x}".format(
                    fld, item[fld]) for fld in item if item[fld])
                adjectives = '|'.join(iterable) or "{:#x}".format(res.int())

                if item['dispFrame'].int():
                    res = "[{:s}] {:s} dispCatchObj={:+#x} dispFrame={:+#x} addressOfHandler={:#x} adjectives={:s}".format(
                        position, description, item['dispCatchObj'].int(),
                        item['dispFrame'].int(),
                        item['addressOfHandler'].int(), adjectives)
                else:
                    res = "[{:s}] {:s} dispCatchObj={:+#x} addressOfHandler={:#x} adjectives={:s}".format(
                        position, description, item['dispCatchObj'].int(),
                        item['addressOfHandler'].int(), adjectives)
                items.append(res)
            return '\n'.join(items)

        def repr(self):
            if self.initializedQ():
                return self.details() + '\n'
            return self.summary()

    _fields_ = [
        (int32, 'tryLow'),
        (int32, 'tryHigh'),
        (int32, 'catchHigh'),
        (int32, 'nCatches'),
        (lambda self: virtualaddress(dyn.clone(
            self._pHandlerArray, length=self['nCatches'].li.int()),
                                     type=dword), 'pHandlerArray'),
    ]
Exemple #28
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))
Exemple #29
0
 def Value(self):
     # wValueLength = number of 16-bit words of wValue
     l = self['wValueLength'].li.num()
     return dyn.clone(pstr.wstring, length=l)
Exemple #30
0
 def __Address(self):
     t = self._object_
     if ptypes.iscontainer(t):
         return self.addressing(dyn.clone(t, blocksize=lambda s: s.getparent(IMAGE_DATA_DIRECTORY)['Size'].li.int()), type=uint32)
     return self.addressing(t, type=uint32)
Exemple #31
0
 def Type(self):
     l = self['wValueLength'].li.int()
     return dyn.clone(parray.block, _object_=dword, blocksize=lambda s:l)
Exemple #32
0
 def Value(self):
     l = self['wValueLength'].li.num()
     return dyn.clone(parray.block, _object_=dword, blocksize=lambda s:l)
Exemple #33
0
 def _object_(self):
     res = self.getparent(Header)['OptionalHeader'].li
     res = loader.IMAGE_LOADCONFIG_DIRECTORY64 if res.is64() else loader.IMAGE_LOADCONFIG_DIRECTORY
     return dyn.clone(res, blocksize=lambda s, cb=self['Size'].li.int(): cb)
Exemple #34
0
 def Type(self):
     # wValueLength = number of 16-bit words of wValue
     l = self['wValueLength'].li.int()
     return dyn.clone(pstr.wstring, length=l)
Exemple #35
0
 def _object_(self):
     res = self.getparent(Header)['OptionalHeader'].li
     res = loader.IMAGE_LOADCONFIG_DIRECTORY64 if res.is64(
     ) else loader.IMAGE_LOADCONFIG_DIRECTORY
     return dyn.clone(res, blocksize=lambda s, cb=self['Size'].li.int(): cb)
Exemple #36
0
 def __StreamHeaders(self):
     res = self['Streams'].li.int()
     return dyn.clone(self._StreamHeaders, length=res)
Exemple #37
0
 def __data(self):
     cb = self['length'].li.Get()
     return dyn.clone(pstr.wstring, length= cb / 2)
Exemple #38
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)
Exemple #39
0
 def __Address(self):
     t = self._object_
     if ptypes.iscontainer(t):
         return self.addressing(dyn.clone(t, blocksize=lambda s: s.getparent(Entry)["Size"].li.num()), type=uint32)
     return self.addressing(t, type=uint32)
Exemple #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()
Exemple #41
0
 def __Symbols(self):
     p = self.getparent(Header)
     header = p.FileHeader()
     return dyn.clone(SymbolTable, length=header['NumberOfSymbols'].int())
Exemple #42
0
import ptypes
from ptypes import pint,pfloat,dyn

class Header(object): pass

## primitives
byte = dyn.clone(pint.uint8_t)
word = dyn.clone(pint.uint16_t)
dword = dyn.clone(pint.uint32_t)
float = dyn.clone(pfloat.single)
double = dyn.clone(pfloat.double)

uint8 = dyn.clone(pint.uint8_t)
int8 = dyn.clone(pint.int8_t)
int16 = dyn.clone(pint.int16_t)
uint16 = dyn.clone(pint.uint16_t)
int32 = dyn.clone(pint.int32_t)
uint32 = dyn.clone(pint.uint32_t)
uint64 = dyn.clone(pint.uint64_t)

class off_t(pint.uint32_t): pass
class addr_t(pint.uint32_t): pass

import datetime
class TimeDateStamp(uint32):
    epoch = datetime.datetime(1970, 1, 1, 0, 0, 0)
    def details(self):
        x = self.epoch + datetime.timedelta( seconds=int(self) )
        return x.strftime('%Y-%m-%d %H:%M:%S')
    def summary(self):
        return '0x{:x} {!r}'.format(self.num(), self.details())
Exemple #43
0
import ptypes, datetime, time
from ptypes import pstruct, parray, ptype, dyn, pstr, pint, pfloat, pbinary

## primitives
byte = dyn.clone(pint.uint8_t)
word = dyn.clone(pint.uint16_t)
dword = dyn.clone(pint.uint32_t)
float = dyn.clone(pfloat.single)
double = dyn.clone(pfloat.double)

uint0 = dyn.clone(pint.uint_t)
int0 = dyn.clone(pint.int_t)
uint8 = dyn.clone(pint.uint8_t)
int8 = dyn.clone(pint.int8_t)
int16 = dyn.clone(pint.int16_t)
uint16 = dyn.clone(pint.uint16_t)
int32 = dyn.clone(pint.int32_t)
uint32 = dyn.clone(pint.uint32_t)
uint64 = dyn.clone(pint.uint64_t)


class off_t(pint.uint32_t):
    pass


class addr_t(pint.uint32_t):
    pass


class VOID(ptype.undefined):
    pass
Exemple #44
0
 def __Address(self):
     t = self._object_
     if ptypes.iscontainer(t):
         return self.addressing(dyn.clone(t, blocksize=lambda s: s.getparent(IMAGE_DATA_DIRECTORY)['Size'].li.int()), type=uint32)
     return self.addressing(t, type=uint32)
Exemple #45
0
 def __StreamHeaders(self):
     res = self['Streams'].li.int()
     return dyn.clone(self._StreamHeaders, length=res)