Exemple #1
0
 public UnsafeWin32MemoryMap(IntPtr hFile, IntPtr hMapping, void *pData, uint size)
 {
     m_fileHandle = hFile.AssumeNotNull();
     m_mapHandle  = hMapping.AssumeNotNull();
     m_pData      = FluentAsserts.AssumeNotNull(pData);
     m_size       = size.AssumeGT(0U);
 }
Exemple #2
0
        private SectionHeader *FindSection(uint virtualAddress)
        {
            if (PEHeader->NumberOfSections == 0)
            {
                return(null);
            }
            //1. Find the greatest lower bound of virtualAddress in the section table.
            var first = SectionTable;
            var min   = SectionTable;
            var max   = SectionTable + PEHeader->NumberOfSections - 1;

            while (max >= first && max != min)
            {
                var mid = (((max - min) + 1) / 2) + min;
                if (mid->VirtualAddress == virtualAddress)
                {
                    return(mid);
                }
                if (virtualAddress < mid->VirtualAddress)
                {
                    max = mid - 1;
                }
                else
                {
                    virtualAddress.AssumeGT(mid->VirtualAddress);
                    min = mid;
                }
            }
            if (max < first)
            {
                return(null);
            }

            //2. Verify that the virtual address fits within the found section
            //(if we select the last section as the glb, the virtual address might be outside it).
            try {
                virtualAddress.AssumeGTE(min->VirtualAddress);
                if (virtualAddress > checked (min->VirtualAddress + min->VirtualSize))
                {
                    return(null);
                }
            }
            catch (OverflowException) {
                return(null);
            }
            return(min);
        }
Exemple #3
0
        public bool Validate(byte *pFileBase, uint fileSize)
        {
            fileSize.AssumeGT(0U);
            fixed(PEHeader *pThis = &this)
            {
                FluentAsserts.Assume(pThis >= pFileBase && pThis < checked (pFileBase + fileSize));
                FluentAsserts.Assume(fileSize - ((byte *)pThis - pFileBase) >= sizeof(PEHeader));

                try {
                    //NOTE: This code could be made more consise using compound conditionals, but this orginization makes
                    //the code much easier to debug.

                    //1. There should be a null symbol table pointer (Partion II, Section 25.2.2 ECMA-335 V 5).
                    if (PointerToSymbolTable != 0)
                    {
                        return(false);
                    }

                    //2. Therefore, there should be 0 symbols (Partion II, Section 25.2.2 ECMA-335 V 5).
                    if (NumberOfSymbols != 0)
                    {
                        return(false);
                    }

                    //3. An optional header should be present, and it size should be at least 224 BYTES.
                    //On 64 bit systems it should be at least 240 bytes, but we won't check that until
                    //we identify the image type when we process the "Optional Header".
                    if (OptionalHeaderSize < 224)
                    {
                        return(false);
                    }

                    //4. The optional header should be within the bounds of the file.

                    if (checked (((byte *)pThis + sizeof(PEHeader) + OptionalHeaderSize) >= pFileBase + fileSize))
                    {
                        return(false);
                    }

                    //5. Is the machine type equal to IMAGE_FILE_MACHINE_UNKNOWN, IMAGE_FILE_MACHINE_I386 or IMAGE_FILE_MACHINE_AMD64?
                    if (!(
                            Machine == MachineType.IMAGE_FILE_MACHINE_UNKNOWN ||
                            Machine == MachineType.IMAGE_FILE_MACHINE_I386 ||
                            Machine == MachineType.IMAGE_FILE_MACHINE_AMD64
                            ))
                    {
                        return(false);
                    }

                    //6. Has the image been marked by a linker as being "complete"
                    if (
                        (Characteristics & ImageCharacteristics.IMAGE_FILE_EXECUTABLE_IMAGE)
                        != ImageCharacteristics.IMAGE_FILE_EXECUTABLE_IMAGE
                        )
                    {
                        return(false);
                    }

                    //7. Are all unsupported flags set to 0? We are overly conservative in the images we accept. If
                    //   something looks like it does not belong in a managed executable we reject it, even if we could
                    //   get away with ignoring it. We should only allow these if real cases come up that require them.
                    if ((Characteristics & s_disallowedImageCharacteristics) != 0)
                    {
                        return(false);
                    }

                    return(true);
                }
                catch (OverflowException) {
                    return(false);
                }
            }
        }
Exemple #4
0
        public bool Verify(uint fileSize, PEHeader *pPEHeader)
        {
            FluentAsserts.AssumeNotNull((void *)pPEHeader);
            fileSize.AssumeGT(0U);

            if (CodeSize > ImageSize)
            {
                return(false);
            }

            if (InitializedDataSize > ImageSize)
            {
                return(false);
            }

            if (UninitializedDataSize > ImageSize)
            {
                return(false);
            }

            try {
                if (checked (CodeSize + InitializedDataSize + UninitializedDataSize) > ImageSize)
                {
                    return(false);
                }
            }
            catch (OverflowException) {
                return(false);
            }

            if (AddressOfEntryPoint != 0 && AddressOfEntryPoint < BaseOfCode)
            {
                return(false);
            }

            if (SectionAlignment < FileAlignment)
            {
                return(false);
            }

            if (FileAlignment < 512 || FileAlignment > 0x10000)
            {
                return(false);
            }

            //Is file alignment a power of 2?
            if (((FileAlignment) & (FileAlignment - 1)) != 0)
            {
                return(false);
            }

            if (Win32VersionValue != 0)
            {
                return(false);
            }

            //Is the header size a multiple of the file alignment?
            if ((HeaderSize & (FileAlignment - 1)) != 0)
            {
                return(false);
            }

            if (HeaderSize > fileSize)
            {
                return(false);
            }

            try {
                //Is the reported header large enough to actually hold all the headers?
                if (
                    HeaderSize < checked (
                        LAYOUT_SIZE
                        + (NumberOfDataDirectories * sizeof(RVAAndSize))
                        + sizeof(PEHeader)
                        + PEFile.MSDosStubSize
                        + (pPEHeader->NumberOfSections * sizeof(SectionHeader))
                        )
                    )
                {
                    return(false);
                }
            }
            catch (OverflowException) {
                return(false);
            }

            if (
                Subsystem != ImageSubsystem.IMAGE_SUBSYSTEM_WINDOWS_CUI &&
                Subsystem != ImageSubsystem.IMAGE_SUBSYSTEM_WINDOWS_GUI
                )
            {
                return(false);
            }

            if ((DllCharacteristics.RESERVED_BITS & DllCharacteristics) != 0)
            {
                return(false);
            }

            if ((DllCharacteristics & DllCharacteristics.IMAGE_DLLCHARACTERISTICS_WDM_DRIVER) != 0)
            {
                return(false);
            }

            if (StackReserveSize < StackCommitSize)
            {
                return(false);
            }

            StackReserveSize.AssumeLTE(SIZE_MAX);
            StackCommitSize.AssumeLTE(SIZE_MAX);

            if (HeapReserveSize < HeapCommitSize)
            {
                return(false);
            }

            HeapReserveSize.AssumeLTE(SIZE_MAX);
            HeapCommitSize.AssumeLTE(SIZE_MAX);

            if (LoaderFlags != 0)
            {
                return(false);
            }

            if (NumberOfDataDirectories < 16)
            {
                return(false);
            }

            if (!DataDirectories[15].IsZero())
            {
                return(false);
            }

            if (CLRRuntimeHeader.IsZero())
            {
                return(false);
            }

            if (CLRRuntimeHeader.Size < sizeof(CLRHeader))
            {
                return(false);
            }

            for (int i = 0; i < NumberOfDataDirectories; ++i)
            {
                if (DataDirectories[i].RVA > ImageSize)
                {
                    return(false);
                }

                if (!DataDirectories[i].IsConsistent())
                {
                    return(false);
                }
            }

            return(true);
        }