Esempio n. 1
0
class IMAGE_LOADCONFIG_DIRECTORY64(pstruct.type):
    _fields_ = [
        (uint32, 'Size'),
        (TimeDateStamp, 'TimeDateStamp'),
        (uint16, 'MajorVersion'),
        (uint16, 'MinorVersion'),
        (uint32, 'GlobalFlagsClear'),
        (uint32, 'GlobalFlagsSet'),
        (uint32, 'CriticalSectionDefaultTimeout'),
        (uint64, 'DeCommitFreeBlockThreshold'),
        (uint64, 'DeCommitTotalFreeThreshold'),
        (realaddress(ptype.undefined, type=uint64), 'LockPrefixTable'),
        (uint64, 'MaximumAllocationSize'),
        (uint64, 'VirtualMemoryThreshold'),
        (uint64, 'ProcessAffinityMask'),
        (uint32, 'ProcessHeapFlags'),
        (uint16, 'CSDVersion'),
        (uint16, 'Reserved1'),
        (realaddress(ptype.undefined, type=uint64), 'EditList'),
        (realaddress(uint64, type=uint64), 'SecurityCookie'),
        (realaddress(
            lambda s: dyn.array(uint64, s.parent['SEHandlerCount'].li.int()),
            type=uint64), 'SEHandlerTable'),
        (uint64, 'SEHandlerCount'),
        (realaddress(uint64, type=uint64), 'GuardCFCheckFunctionPointer'),
        (realaddress(uint64, type=uint64), 'GuardCFDispatchFunctionPointer'),
        (realaddress(lambda s: dyn.array(
            uint64, s.parent['GuardCFFunctionCount'].li.int()),
                     type=uint64), 'GuardCFFunctionTable'),
        (uint64, 'GuardCFFunctionCount'),
        (pbinary.littleendian(IMAGE_GUARD_), 'GuardFlags'),
        (IMAGE_LOAD_CONFIG_CODE_INTEGRITY, 'CodeIntegrity'),
        (realaddress(lambda s: dyn.array(
            uint64, s.parent['GuardAddressTakenIatEntryCount'].li.int()),
                     type=uint64), 'GuardAddressTakenIatEntryTable'),
        (uint64, 'GuardAddressTakenIatEntryCount'),
        (realaddress(lambda s: dyn.array(
            uint64, s.parent['GuardLongJumpTargetCount'].li.int()),
                     type=uint64), 'GuardLongJumpTargetTable'),
        (uint64, 'GuardLongJumpTargetCount'),
        (realaddress(ptype.undefined, type=uint64), 'DynamicValueRelocTable'),
        (realaddress(ptype.undefined, type=uint64), 'CHPEMetadataPointer'),
        (realaddress(uint64, type=uint64), 'GuardRFFailureRoutine'),
        (realaddress(uint64,
                     type=uint64), 'GuardRFFailureRoutineFunctionPointer'),
        (uint32, 'DynamicValueRelocTableOffset'),
        (uint16, 'DynamicValueRelocTableSection'),
        (uint16, 'Reserved2'),
        (realaddress(uint64,
                     type=uint64), 'GuardRFVerifyStackPointerFunctionPointer'),
        (uint32, 'HotPatchTableOffset'),
        (uint32, 'Reserved3'),
        (realaddress(pstr.szwstring,
                     type=uint64), 'AddressOfSomeUnicodeString'),
    ]
Esempio n. 2
0
class IMAGE_RESOURCE_DIRECTORY_ENTRY_RVA_DATA(IMAGE_RESOURCE_DIRECTORY_ENTRY_RVA):
    class RVAType(pbinary.struct):
        _fields_ = [(1, 'DataIsDirectory'), (31, 'OffsetToDirectory')]
        def get(self):
            return self['OffsetToDirectory']
        def set(self, value):
            self['DataIsDirectory'] = 0
            self['OffsetToDirecotry'] = value
            return self
    _value_ = pbinary.littleendian(RVAType)

    def _object_(self):
        return IMAGE_RESOURCE_DIRECTORY if self.object['DataIsDirectory'] else IMAGE_RESOURCE_DATA_ENTRY
Esempio n. 3
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)

    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)'),
        (pbinary.littleendian(StorageFlags), 'Flags'),
        (pint.uint16_t, 'Streams'),
        (__StreamHeaders, 'StreamHeaders'),
        (__StreamData, 'StreamData'),
    ]
Esempio n. 4
0
class IMAGE_RESOURCE_DIRECTORY_ENTRY_RVA_NAME(IMAGE_RESOURCE_DIRECTORY_ENTRY_RVA):
    class RVAType(pbinary.struct):
        _fields_ = [(1, 'NameIsString'), (31, 'NameOffset')]
        def get(self):
            return self['NameOffset']
        def set(self, value):
            self['NameIsString'] = 0
            self['NameOffset'] = value
            return self
    _value_ = pbinary.littleendian(RVAType)

    def _object_(self):
        return IMAGE_RESOURCE_DIRECTORY_STRING_U if self.object['NameIsString'] else ptype.undefined

    def get(self):
        if self.object['NameIsString'] == 0:
            return self.object['NameOffset']
        return self.d.li.str()
Esempio n. 5
0
class IMAGE_RESOURCE_DIRECTORY_ENTRY_RVA(ptype.rpointer_t):
    class RVAType(pbinary.struct):
        _fields_ = [(1, 'type'), (31, 'offset')]
        def get(self):
            return self['offset']
        def set(self, value):
            self['type'] = 0
            self['offset'] = value
            return self
    _value_ = pbinary.littleendian(RVAType)
    def _baseobject_(self):
        base = self.getparent(headers.IMAGE_DATA_DIRECTORY)['Address']
        if base.int() == 0:
            raise ValueError("No Resource Data Directory Entry")
        return base.d
    def encode(self, object, **attrs):
        raise NotImplementedError
    def summary(self, **attrs):
        return self.object.summary(**attrs)
Esempio n. 6
0
class IMAGE_OPTIONAL_HEADER(pstruct.type):
    """PE Executable Optional Header"""
    def is64(self):
        '''Returns True if a 64-bit executable'''
        if len(self.v) > 0:
            magic = self['Magic']
            return magic.li.int() == 0x20b
        return False

    _fields_ = [
        ( IMAGE_NT_OPTIONAL_MAGIC, 'Magic' ),
        ( uint8, 'MajorLinkerVersion' ),
        ( uint8, 'MinorLinkerVersion' ),
        ( uint32, 'SizeOfCode' ),
        ( uint32, 'SizeOfInitializedData' ),
        ( uint32, 'SizeOfUninitializedData' ),
        ( virtualaddress(ptype.undefined, type=uint32), 'AddressOfEntryPoint' ),
        ( uint32, 'BaseOfCode' ),
        ( lambda s: pint.uint_t if s.is64() else uint32, 'BaseOfData' ),

        ( lambda s: uint64 if s.is64() else uint32, 'ImageBase' ),
        ( uint32, 'SectionAlignment' ),
        ( uint32, 'FileAlignment' ),
        ( uint16, 'MajorOperatingSystemVersion' ),
        ( uint16, 'MinorOperatingSystemVersion' ),
        ( uint16, 'MajorImageVersion' ),
        ( uint16, 'MinorImageVersion' ),
        ( uint16, 'MajorSubsystemVersion' ),
        ( uint16, 'MinorSubsystemVersion' ),
        ( uint32, 'Win32VersionValue' ),
        ( uint32, 'SizeOfImage' ),
        ( uint32, 'SizeOfHeaders' ),
        ( uint32, 'CheckSum' ),
        ( IMAGE_SUBSYSTEM_, 'Subsystem' ),
        ( pbinary.littleendian(IMAGE_DLLCHARACTERISTICS), 'DllCharacteristics' ),
        ( lambda s: uint64 if s.is64() else uint32, 'SizeOfStackReserve' ),
        ( lambda s: uint64 if s.is64() else uint32, 'SizeOfStackCommit' ),
        ( lambda s: uint64 if s.is64() else uint32, 'SizeOfHeapReserve' ),
        ( lambda s: uint64 if s.is64() else uint32, 'SizeOfHeapCommit' ),
        ( uint32, 'LoaderFlags' ),
        ( uint32, 'NumberOfRvaAndSizes' ),
    ]
Esempio n. 7
0
class IMAGE_FILE_HEADER(pstruct.type):
    """PE Executable File Header"""
    class Characteristics(pbinary.flags):
        _fields_ = [
            (1, 'BYTES_REVERSED_HI'), (1, 'UP_SYSTEM_ONLY'), (1, 'DLL'), (1, 'SYSTEM'),
            (1, 'NET_RUN_FROM_SWAP'), (1, 'REMOVABLE_RUN_FROM_SWAP'), (1, 'DEBUG_STRIPPED'),
            (1, '32BIT_MACHINE'), (1, 'BYTES_REVERSED_LO'), (1, 'reserved_9'),
            (1, 'LARGE_ADDRESS_AWARE'), (1, 'AGGRESSIVE_WS_TRIM'), (1, 'LOCAL_SYMS_STRIPPED'),
            (1, 'LINE_NUMS_STRIPPED'), (1, 'EXECUTABLE_IMAGE'), (1, 'RELOCS_STRIPPED'),
        ]

    _fields_ = [
        (Machine, 'Machine'),
        (uint16, 'NumberOfSections'),
        (TimeDateStamp, 'TimeDateStamp'),
        (fileoffset(symbols.SymbolTableAndStringTable, type=uint32), 'PointerToSymbolTable'),
        (uint32, 'NumberOfSymbols'),
        (word, 'SizeOfOptionalHeader'),
        (pbinary.littleendian(Characteristics), 'Characteristics')
    ]
Esempio n. 8
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()
Esempio n. 9
0
class IMAGE_LOADCONFIG_DIRECTORY(pstruct.type):
    # FIXME: The size field in the DataDirectory is used to determine which
    #        IMAGE_LOADCONFIG_DIRECTORY to use. Instead we're cheating and
    #        using the size specified in the data-directory entry and a
    #        feature of pstruct.type when defining a custom .blocksize(). A
    #        proper implementation should check the 'Size' field and then
    #        use this to determine which IMAGE_LOADCONFIG_DIRECTORY
    #        should be used. Once that's done, then we can define a
    #        sub-object that chooses the correct IMAGE_LOADCONFIG_DIRECTORY
    #        to use.

    _fields_ = [
        (uint32, 'Size'),
        (TimeDateStamp, 'TimeDateStamp'),
        (uint16, 'MajorVersion'),
        (uint16, 'MinorVersion'),
        (uint32, 'GlobalFlagsClear'),  # FIXME
        (uint32, 'GlobalFlagsSet'),  # FIXME
        (uint32, 'CriticalSectionDefaultTimeout'),
        (uint32, 'DeCommitFreeBlockThreshold'),
        (uint32, 'DeCommitTotalFreeThreshold'),
        (realaddress(ptype.undefined, type=uint32),
         'LockPrefixTable'),  # XXX: NULL-terminated list of VAs
        (uint32, 'MaximumAllocationSize'),
        (uint32, 'VirtualMemoryThreshold'),
        (uint32, 'ProcessAffinityMask'),
        (uint32, 'ProcessHeapFlags'),  # FIXME: where are these flags at?
        (uint16, 'CSDVersion'),
        (uint16, 'Reserved'),
        (realaddress(ptype.undefined, type=uint32),
         'EditList'),  # XXX: also probably a NULL-terminated list of VAs
        (realaddress(uint32, type=uint32), 'SecurityCookie'),
        (realaddress(
            lambda s: dyn.array(uint32, s.parent['SEHandlerCount'].li.int()),
            type=uint32), 'SEHandlerTable'),
        (uint32, 'SEHandlerCount'),
        (realaddress(uint32, type=uint32), 'GuardCFCheckFunctionPointer'),
        (realaddress(uint32, type=uint32), 'GuardCFDispatchFunctionPointer'),
        (realaddress(lambda s: dyn.array(
            uint32, s.parent['GuardCFFunctionCount'].li.int()),
                     type=uint32), 'GuardCFFunctionTable'),
        (uint32, 'GuardCFFunctionCount'),
        (pbinary.littleendian(IMAGE_GUARD_), 'GuardFlags'),
        (IMAGE_LOAD_CONFIG_CODE_INTEGRITY, 'CodeIntegrity'),
        (realaddress(lambda s: dyn.array(
            uint32, s.parent['GuardAddressTakenIatEntryCount'].li.int()),
                     type=uint32), 'GuardAddressTakenIatEntryTable'),
        (uint32, 'GuardAddressTakenIatEntryCount'),
        (realaddress(lambda s: dyn.array(
            uint32, s.parent['GuardLongJumpTargetCount'].li.int()),
                     type=uint32), 'GuardLongJumpTargetTable'),
        (uint32, 'GuardLongJumpTargetCount'),
        (realaddress(ptype.undefined, type=uint32), 'DynamicValueRelocTable'
         ),  # XXX: Probably another NULL-terminated list of VAs
        (realaddress(ptype.undefined,
                     type=uint32), 'CHPEMetadataPointer'),  # FIXME
        (realaddress(uint32, type=uint32), 'GuardRFFailureRoutine'),
        (realaddress(uint32,
                     type=uint32), 'GuardRFFailureRoutineFunctionPointer'),
        (uint32, 'DynamicValueRelocTableOffset'
         ),  # XXX: depends on DynamicValueRelocTableSection
        (uint16, 'DynamicValueRelocTableSection'),
        (uint16, 'Reserved2'),
        (realaddress(uint32,
                     type=uint32), 'GuardRFVerifyStackPointerFunctionPointer'),
        (uint32, 'HotPatchTableOffset'),
        (realaddress(pstr.wstring, type=uint32), 'AddressOfSomeUnicodeString'),
        (uint32, 'Reserved3'),
    ]
Esempio n. 10
0
class IMAGE_LOAD_CONFIG_DIRECTORY64(IMAGE_LOAD_CONFIG_DIRECTORY):
    _fields_ = [
        (DWORD, 'Size'),
        (TimeDateStamp, 'TimeDateStamp'),
        (WORD, 'MajorVersion'),
        (WORD, 'MinorVersion'),
        (DWORD, 'GlobalFlagsClear'),
        (DWORD, 'GlobalFlagsSet'),
        (DWORD, 'CriticalSectionDefaultTimeout'),
        (ULONGLONG, 'DeCommitFreeBlockThreshold'),
        (ULONGLONG, 'DeCommitTotalFreeThreshold'),
        (realaddress(VOID, type=ULONGLONG), 'LockPrefixTable'),
        (ULONGLONG, 'MaximumAllocationSize'),
        (ULONGLONG, 'VirtualMemoryThreshold'),
        (ULONGLONG, 'ProcessAffinityMask'),
        (DWORD, 'ProcessHeapFlags'),
        (WORD, 'CSDVersion'),
        (LOAD_LIBRARY_SEARCH_, 'DependentLoadFlags'),
        (realaddress(VOID, type=ULONGLONG), 'EditList'),
        (realaddress(ULONGLONG, type=ULONGLONG), 'SecurityCookie'),
        (realaddress(lambda self: dyn.array(
            ULONGLONG, self.parent['SEHandlerCount'].li.int()),
                     type=ULONGLONG), 'SEHandlerTable'),
        (ULONGLONG, 'SEHandlerCount'),
        (realaddress(realaddress(VOID, type=ULONGLONG),
                     type=ULONGLONG), 'GuardCFCheckFunctionPointer'),
        (realaddress(realaddress(VOID, type=ULONGLONG),
                     type=ULONGLONG), 'GuardCFDispatchFunctionPointer'),
        (realaddress(lambda self: dyn.array(
            virtualaddress(VOID, type=DWORD), self.parent[
                'GuardCFFunctionCount'].li.int()),
                     type=ULONGLONG), 'GuardCFFunctionTable'),
        (ULONGLONG, 'GuardCFFunctionCount'),
        (pbinary.littleendian(IMAGE_GUARD_), 'GuardFlags'),
        (IMAGE_LOAD_CONFIG_CODE_INTEGRITY, 'CodeIntegrity'),
        (realaddress(lambda self: dyn.array(
            ULONGLONG, self.parent['GuardAddressTakenIatEntryCount'].li.int()),
                     type=ULONGLONG), 'GuardAddressTakenIatEntryTable'),
        (ULONGLONG, 'GuardAddressTakenIatEntryCount'),
        (realaddress(lambda self: dyn.array(
            ULONGLONG, self.parent['GuardLongJumpTargetCount'].li.int()),
                     type=ULONGLONG), 'GuardLongJumpTargetTable'),
        (ULONGLONG, 'GuardLongJumpTargetCount'),
        (realaddress(IMAGE_DYNAMIC_RELOCATION_TABLE,
                     type=ULONGLONG), 'DynamicValueRelocTable'),
        (realaddress(VOID, type=ULONGLONG), 'CHPEMetadataPointer'),
        (realaddress(VOID, type=ULONGLONG), 'GuardRFFailureRoutine'),
        (realaddress(VOID,
                     type=ULONGLONG), 'GuardRFFailureRoutineFunctionPointer'),
        (DWORD, 'DynamicValueRelocTableOffset'),
        (WORD, 'DynamicValueRelocTableSection'),
        (WORD, 'Reserved2'),
        (realaddress(ULONGLONG, type=ULONGLONG),
         'GuardRFVerifyStackPointerFunctionPointer'),
        (DWORD, 'HotPatchTableOffset'),
        (DWORD, 'Reserved3'),
        (realaddress(IMAGE_ENCLAVE_CONFIG64,
                     type=ULONGLONG), 'EnclaveConfigurationPointer'),
        (realaddress(VOID, type=ULONGLONG), 'VolatileMetadataPointer'),
        (realaddress(lambda self: dyn.array(
            ULONGLONG, self.parent['GuardEHContinuationCount'].li.int()),
                     type=ULONGLONG), 'GuardEHContinuationTable'),
        (ULONGLONG, 'GuardEHContinuationCount'),
        (realaddress(VOID, type=ULONGLONG), 'GuardXFGCheckFunctionPointer'),
        (realaddress(VOID, type=ULONGLONG), 'GuardXFGDispatchFunctionPointer'),
        (realaddress(VOID,
                     type=ULONGLONG), 'GuardXFGTableDispatchFunctionPointer'),
        (ULONGLONG, 'CastGuardOsDeterminedFailureMode'),
    ]
Esempio n. 11
0
class HTables(pstruct.type):
    type = "#~"

    class HeapSizes(pbinary.flags):
        _fields_ = [
            (5, 'Unused'),
            (1, 'HBlob'),
            (1, 'HGUID'),
            (1, 'HStrings'),
        ]

    class BitVector(pbinary.array):
        _object_ = 1

        def index(self, index):
            res = len(self) - index
            return self[res - 1]

        def indices(self, crit):
            return [
                index for index, value in enumerate(reversed(self))
                if crit(value)
            ]

    class _Valid(BitVector):
        length = 64

        def indices(self):
            return super(HTables._Valid, self).indices(bool)

        def summary(self):
            return ', '.join(map('{:d}'.format, self.indices()))

    class _Sorted(BitVector):
        length = 64

        def indices(self):
            return super(HTables._Sorted, self).indices(bool)

    class _RowLengths(parray.type):
        length = 64

        def _object_(self):
            res, index = self.getparent(HTables), len(self.value)
            present = res['Valid'].li.index
            return pint.uint32_t if present(index) else pint.uint_t

    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)))

    _fields_ = [
        (pint.uint32_t, 'Reserved'),
        (pint.uint8_t, 'MajorVersion'),
        (pint.uint8_t, 'MinorVersion'),
        (HeapSizes, 'HeapSizes'),
        (pint.uint8_t, 'Reserved'),
        (pbinary.littleendian(_Valid), 'Valid'),
        (pbinary.littleendian(_Sorted), 'Sorted'),
        (_RowLengths, 'Rows'),
        (Tables, 'Tables'),
        (__padding_Tables, 'padding(Tables)'),
    ]