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