public static async Task <CLRMetaDataHeader> LoadAsync(PortableExecutableImage image, Location mdLocation) { try { var stream = image.GetStream(); var rva = mdLocation.RelativeVirtualAddress; var va = mdLocation.VirtualAddress; var offset = mdLocation.FileOffset; var section = mdLocation.Section; stream.Seek(offset.ToInt64(), SeekOrigin.Begin); var signature = await stream.ReadUInt32Async().ConfigureAwait(false); if (signature != CLR_METADATA_SIGNATURE) { throw new PortableExecutableImageException(image, "Incorrect signature found in CLR meta-data header."); } var majorVersion = await stream.ReadUInt16Async().ConfigureAwait(false); var minorVersion = await stream.ReadUInt16Async().ConfigureAwait(false); var reserved = await stream.ReadUInt32Async().ConfigureAwait(false); var versionLength = await stream.ReadInt32Async().ConfigureAwait(false); var version = await stream.ReadStringAsync(versionLength).ConfigureAwait(false); var flags = await stream.ReadUInt16Async().ConfigureAwait(false); var streams = await stream.ReadUInt16Async().ConfigureAwait(false); var size = sizeof(uint) + sizeof(ushort) + sizeof(ushort) + sizeof(uint) + sizeof(uint) + versionLength + sizeof(ushort) + sizeof(ushort); var location = new Location(image, offset, rva, va, size.ToUInt32(), size.ToUInt32(), section); var header = new CLRMetaDataHeader(image, location) { Signature = signature, MajorVersion = majorVersion, MinorVersion = minorVersion, Reserved = reserved, VersionLength = versionLength, Version = version, Flags = flags, Streams = streams }; return(header); } catch (Exception ex) { if (ex is PortableExecutableImageException) { throw; } throw new PortableExecutableImageException(image, "Could not read CLR meta-data header from stream.", ex); } }
public static async Task <DebugDirectory> GetAsync(PortableExecutableImage image) { if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.Debug)) { return(null); } var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.Debug]; if (DataDirectory.IsNullOrEmpty(dataDirectory)) { return(null); } try { var calc = image.GetCalculator(); var section = calc.RVAToSection(dataDirectory.VirtualAddress); var fileOffset = calc.RVAToOffset(section, dataDirectory.VirtualAddress); var imageBase = image.NTHeaders.OptionalHeader.ImageBase; var location = new Location(image, fileOffset, dataDirectory.VirtualAddress, imageBase + dataDirectory.VirtualAddress, dataDirectory.Size, dataDirectory.Size, section); var stream = image.GetStream(); stream.Seek(fileOffset.ToInt32(), SeekOrigin.Begin); var entrySize = Utils.SizeOf <IMAGE_DEBUG_DIRECTORY>(); var entryCount = dataDirectory.Size / entrySize; var entries = new Tuple <ulong, IMAGE_DEBUG_DIRECTORY> [entryCount]; for (var i = 0; i < entryCount; i++) { var entry = await stream.ReadStructAsync <IMAGE_DEBUG_DIRECTORY>(entrySize).ConfigureAwait(false); entries[i] = new Tuple <ulong, IMAGE_DEBUG_DIRECTORY>(fileOffset, entry); } var directoryEntries = LoadEntries(image, entrySize, entries); var directory = new DebugDirectory(image, dataDirectory, location, directoryEntries); return(directory); } catch (Exception ex) { throw new PortableExecutableImageException(image, "Could not read debug directory from stream.", ex); } }