internal CorHeader(ref PEBinaryReader reader) { // byte count reader.ReadInt32(); MajorRuntimeVersion = reader.ReadUInt16(); MinorRuntimeVersion = reader.ReadUInt16(); MetadataDirectory = new DirectoryEntry(ref reader); Flags = (CorFlags)reader.ReadUInt32(); EntryPointTokenOrRelativeVirtualAddress = reader.ReadInt32(); ResourcesDirectory = new DirectoryEntry(ref reader); StrongNameSignatureDirectory = new DirectoryEntry(ref reader); CodeManagerTableDirectory = new DirectoryEntry(ref reader); VtableFixupsDirectory = new DirectoryEntry(ref reader); ExportAddressTableJumpsDirectory = new DirectoryEntry(ref reader); ManagedNativeHeaderDirectory = new DirectoryEntry(ref reader); }
private BlobBuilder SerializeTextSection(SectionLocation location) { var sectionBuilder = new BlobBuilder(); var metadataBuilder = new BlobBuilder(); var metadataSizes = _metadataRootBuilder.Sizes; var textSection = new ManagedTextSection( imageCharacteristics: Header.ImageCharacteristics, machine: Header.Machine, ilStreamSize: _ilStream.Count, metadataSize: metadataSizes.MetadataSize, resourceDataSize: _managedResourcesOpt?.Count ?? 0, strongNameSignatureSize: _strongNameSignatureSize, debugDataSize: _debugDirectoryBuilderOpt?.Size ?? 0, mappedFieldDataSize: _mappedFieldDataOpt?.Count ?? 0); int methodBodyStreamRva = location.RelativeVirtualAddress + textSection.OffsetToILStream; int mappedFieldDataStreamRva = location.RelativeVirtualAddress + textSection.CalculateOffsetToMappedFieldDataStream(); _metadataRootBuilder.Serialize(metadataBuilder, methodBodyStreamRva, mappedFieldDataStreamRva); DirectoryEntry debugDirectoryEntry; BlobBuilder debugTableBuilderOpt; if (_debugDirectoryBuilderOpt != null) { int debugDirectoryOffset = textSection.ComputeOffsetToDebugDirectory(); debugTableBuilderOpt = new BlobBuilder(_debugDirectoryBuilderOpt.TableSize); _debugDirectoryBuilderOpt.Serialize(debugTableBuilderOpt, location, debugDirectoryOffset); // Only the size of the fixed part of the debug table goes here. debugDirectoryEntry = new DirectoryEntry( location.RelativeVirtualAddress + debugDirectoryOffset, _debugDirectoryBuilderOpt.TableSize); } else { debugTableBuilderOpt = null; debugDirectoryEntry = default(DirectoryEntry); } _lazyEntryPointAddress = textSection.GetEntryPointAddress(location.RelativeVirtualAddress); textSection.Serialize( sectionBuilder, location.RelativeVirtualAddress, _entryPointOpt.IsNil ? 0 : MetadataTokens.GetToken(_entryPointOpt), _corFlags, Header.ImageBase, metadataBuilder, _ilStream, _mappedFieldDataOpt, _managedResourcesOpt, debugTableBuilderOpt, out _lazyStrongNameSignature); _peDirectoriesBuilder.AddressOfEntryPoint = _lazyEntryPointAddress; _peDirectoriesBuilder.DebugTable = debugDirectoryEntry; _peDirectoriesBuilder.ImportAddressTable = textSection.GetImportAddressTableDirectoryEntry(location.RelativeVirtualAddress); _peDirectoriesBuilder.ImportTable = textSection.GetImportTableDirectoryEntry(location.RelativeVirtualAddress); _peDirectoriesBuilder.CorHeaderTable = textSection.GetCorHeaderDirectoryEntry(location.RelativeVirtualAddress); return sectionBuilder; }
internal bool TryGetDirectoryOffset(DirectoryEntry directory, out int offset, bool canCrossSectionBoundary) { int sectionIndex = GetContainingSectionIndex(directory.RelativeVirtualAddress); if (sectionIndex < 0) { offset = -1; return false; } int relativeOffset = directory.RelativeVirtualAddress - _sectionHeaders[sectionIndex].VirtualAddress; if (!canCrossSectionBoundary && directory.Size > _sectionHeaders[sectionIndex].VirtualSize - relativeOffset) { throw new BadImageFormatException(SR.SectionTooSmall); } offset = _sectionHeaders[sectionIndex].PointerToRawData + relativeOffset; return true; }
/// <summary> /// Gets the offset (in bytes) from the start of the image to the given directory data. /// </summary> /// <param name="directory">PE directory entry</param> /// <param name="offset">Offset from the start of the image to the given directory data</param> /// <returns>True if the directory data is found, false otherwise.</returns> public bool TryGetDirectoryOffset(DirectoryEntry directory, out int offset) { return TryGetDirectoryOffset(directory, out offset, canCrossSectionBoundary: true); }
internal PEHeader(ref PEBinaryReader reader) { PEMagic magic = (PEMagic)reader.ReadUInt16(); if (magic != PEMagic.PE32 && magic != PEMagic.PE32Plus) { throw new BadImageFormatException(SR.UnknownPEMagicValue); } Magic = magic; MajorLinkerVersion = reader.ReadByte(); MinorLinkerVersion = reader.ReadByte(); SizeOfCode = reader.ReadInt32(); SizeOfInitializedData = reader.ReadInt32(); SizeOfUninitializedData = reader.ReadInt32(); AddressOfEntryPoint = reader.ReadInt32(); BaseOfCode = reader.ReadInt32(); if (magic == PEMagic.PE32Plus) { BaseOfData = 0; // not present } else { Debug.Assert(magic == PEMagic.PE32); BaseOfData = reader.ReadInt32(); } if (magic == PEMagic.PE32Plus) { ImageBase = reader.ReadUInt64(); } else { ImageBase = reader.ReadUInt32(); } // NT additional fields: SectionAlignment = reader.ReadInt32(); FileAlignment = reader.ReadInt32(); MajorOperatingSystemVersion = reader.ReadUInt16(); MinorOperatingSystemVersion = reader.ReadUInt16(); MajorImageVersion = reader.ReadUInt16(); MinorImageVersion = reader.ReadUInt16(); MajorSubsystemVersion = reader.ReadUInt16(); MinorSubsystemVersion = reader.ReadUInt16(); // Win32VersionValue (reserved, should be 0) reader.ReadUInt32(); SizeOfImage = reader.ReadInt32(); SizeOfHeaders = reader.ReadInt32(); CheckSum = reader.ReadUInt32(); Subsystem = (Subsystem)reader.ReadUInt16(); DllCharacteristics = (DllCharacteristics)reader.ReadUInt16(); if (magic == PEMagic.PE32Plus) { SizeOfStackReserve = reader.ReadUInt64(); SizeOfStackCommit = reader.ReadUInt64(); SizeOfHeapReserve = reader.ReadUInt64(); SizeOfHeapCommit = reader.ReadUInt64(); } else { SizeOfStackReserve = reader.ReadUInt32(); SizeOfStackCommit = reader.ReadUInt32(); SizeOfHeapReserve = reader.ReadUInt32(); SizeOfHeapCommit = reader.ReadUInt32(); } // loader flags reader.ReadUInt32(); NumberOfRvaAndSizes = reader.ReadInt32(); // directory entries: ExportTableDirectory = new DirectoryEntry(ref reader); ImportTableDirectory = new DirectoryEntry(ref reader); ResourceTableDirectory = new DirectoryEntry(ref reader); ExceptionTableDirectory = new DirectoryEntry(ref reader); CertificateTableDirectory = new DirectoryEntry(ref reader); BaseRelocationTableDirectory = new DirectoryEntry(ref reader); DebugTableDirectory = new DirectoryEntry(ref reader); CopyrightTableDirectory = new DirectoryEntry(ref reader); GlobalPointerTableDirectory = new DirectoryEntry(ref reader); ThreadLocalStorageTableDirectory = new DirectoryEntry(ref reader); LoadConfigTableDirectory = new DirectoryEntry(ref reader); BoundImportTableDirectory = new DirectoryEntry(ref reader); ImportAddressTableDirectory = new DirectoryEntry(ref reader); DelayImportTableDirectory = new DirectoryEntry(ref reader); CorHeaderTableDirectory = new DirectoryEntry(ref reader); // ReservedDirectory (should be 0, 0) new DirectoryEntry(ref reader); }
/// <summary> /// Gets the offset (in bytes) from the start of the image to the given directory entry. /// </summary> /// <param name="directory"></param> /// <param name="offset"></param> /// <returns>The section containing the directory could not be found.</returns> /// <exception cref="BadImageFormatException">The section containing the</exception> public bool TryGetDirectoryOffset(DirectoryEntry directory, out int offset) { int sectionIndex = GetContainingSectionIndex(directory.RelativeVirtualAddress); if (sectionIndex < 0) { offset = -1; return false; } int relativeOffset = directory.RelativeVirtualAddress - _sectionHeaders[sectionIndex].VirtualAddress; if (directory.Size > _sectionHeaders[sectionIndex].VirtualSize - relativeOffset) { throw new BadImageFormatException(MetadataResources.SectionTooSmall); } offset = _sectionHeaders[sectionIndex].PointerToRawData + relativeOffset; return true; }
/// <summary> /// Gets the offset (in bytes) from the start of the image to the given directory data. /// </summary> /// <param name="directory">PE directory entry</param> /// <param name="offset">Offset from the start of the image to the given directory data</param> /// <returns>True if the directory data is found, false otherwise.</returns> public bool TryGetDirectoryOffset(DirectoryEntry directory, out int offset) { return(TryGetDirectoryOffset(directory, out offset, canCrossSectionBoundary: true)); }
private BlobBuilder SerializeTextSection(SectionLocation location) { var sectionBuilder = new BlobBuilder(); var metadataBuilder = new BlobBuilder(); var metadataSizes = _metadataRootBuilder.Sizes; var textSection = new ManagedTextSection( imageCharacteristics: Header.ImageCharacteristics, machine: Header.Machine, ilStreamSize: _ilStream.Count, metadataSize: metadataSizes.MetadataSize, resourceDataSize: _managedResourcesOpt?.Count ?? 0, strongNameSignatureSize: _strongNameSignatureSize, debugDataSize: _debugDirectoryBuilderOpt?.Size ?? 0, mappedFieldDataSize: _mappedFieldDataOpt?.Count ?? 0); int methodBodyStreamRva = location.RelativeVirtualAddress + textSection.OffsetToILStream; int mappedFieldDataStreamRva = location.RelativeVirtualAddress + textSection.CalculateOffsetToMappedFieldDataStream(); _metadataRootBuilder.Serialize(metadataBuilder, methodBodyStreamRva, mappedFieldDataStreamRva); DirectoryEntry debugDirectoryEntry; BlobBuilder debugTableBuilderOpt; if (_debugDirectoryBuilderOpt != null) { int debugDirectoryOffset = textSection.ComputeOffsetToDebugDirectory(); debugTableBuilderOpt = new BlobBuilder(_debugDirectoryBuilderOpt.TableSize); _debugDirectoryBuilderOpt.Serialize(debugTableBuilderOpt, location, debugDirectoryOffset); // Only the size of the fixed part of the debug table goes here. debugDirectoryEntry = new DirectoryEntry( location.RelativeVirtualAddress + debugDirectoryOffset, _debugDirectoryBuilderOpt.TableSize); } else { debugTableBuilderOpt = null; debugDirectoryEntry = default(DirectoryEntry); } _lazyEntryPointAddress = textSection.GetEntryPointAddress(location.RelativeVirtualAddress); textSection.Serialize( sectionBuilder, location.RelativeVirtualAddress, _entryPointOpt.IsNil ? 0 : MetadataTokens.GetToken(_entryPointOpt), _corFlags, Header.ImageBase, metadataBuilder, _ilStream, _mappedFieldDataOpt, _managedResourcesOpt, debugTableBuilderOpt, out _lazyStrongNameSignature); _peDirectoriesBuilder.AddressOfEntryPoint = _lazyEntryPointAddress; _peDirectoriesBuilder.DebugTable = debugDirectoryEntry; _peDirectoriesBuilder.ImportAddressTable = textSection.GetImportAddressTableDirectoryEntry(location.RelativeVirtualAddress); _peDirectoriesBuilder.ImportTable = textSection.GetImportTableDirectoryEntry(location.RelativeVirtualAddress); _peDirectoriesBuilder.CorHeaderTable = textSection.GetCorHeaderDirectoryEntry(location.RelativeVirtualAddress); return(sectionBuilder); }