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); } }
internal CLRMetaData(PortableExecutableImage image, Location location, CLRMetaDataHeader header, CLRMetaDataStreamTable streamTable, CLRMetaDataStreams streams) { _image = image; Location = location; Header = header; StreamTable = streamTable; Streams = streams; }
internal static async Task <CLRMetaData> GetAsync(PortableExecutableImage image, CLRHeader header) { var calc = image.GetCalculator(); var imageBase = image.NTHeaders.OptionalHeader.ImageBase; var rva = header.MetaDataAddress; var va = imageBase + rva; var offset = calc.RVAToOffset(rva); var size = header.MetaDataSize; var section = calc.RVAToSection(rva); var location = new Location(image, offset, rva, va, size, size, section); var metaDataHeader = await CLRMetaDataHeader.LoadAsync(image, location).ConfigureAwait(false); var metaDataStreamTable = await CLRMetaDataStreamTable.LoadAsync(image, metaDataHeader).ConfigureAwait(false); var metaDataStreams = await CLRMetaDataStreams.LoadAsync(image, location, metaDataStreamTable).ConfigureAwait(false); var metaData = new CLRMetaData(image, location, metaDataHeader, metaDataStreamTable, metaDataStreams); return(metaData); }
private static async Task <CLRMetaDataStreamTableEntry[]> LoadTableAsync(PortableExecutableImage image, CLRMetaDataHeader header, ulong baseOffset, ulong imageBase) { var stream = image.GetStream(); stream.Seek(baseOffset.ToInt64(), SeekOrigin.Begin); var entries = new List <CLRMetaDataStreamTableEntry>(); var offset = baseOffset; for (var i = 0; i < header.Streams; i++) { var size = 0U; var streamOffset = await stream.ReadUInt32Async().ConfigureAwait(false); size += sizeof(uint); var streamSize = await stream.ReadUInt32Async().ConfigureAwait(false); size += sizeof(uint); var streamName = new StringBuilder(256); while (true) { var b = await stream.ReadByteAsync().ConfigureAwait(false); size += 1; if (b <= 0) { break; } streamName.Append((char)b); } while (true) { if (stream.Position % 4 != 0) { await stream.ReadByteAsync().ConfigureAwait(false); size += 1; } else { break; } } var calc = image.GetCalculator(); var rva = calc.OffsetToRVA(offset); var va = imageBase + rva; var section = calc.RVAToSection(rva); var location = new Location(image, offset, rva, va, size, size, section); var entry = new CLRMetaDataStreamTableEntry(image, location, streamOffset, streamSize, streamName.ToString()); entries.Add(entry); offset += size; } return(entries.ToArray()); }
public static async Task <CLRMetaDataStreamTable> LoadAsync(PortableExecutableImage image, CLRMetaDataHeader header) { try { var calc = image.GetCalculator(); var imageBase = image.NTHeaders.OptionalHeader.ImageBase; var offset = header.Location.FileOffset + header.Location.FileSize; var rva = calc.OffsetToRVA(offset); var va = imageBase + rva; var entries = await LoadTableAsync(image, header, offset, imageBase).ConfigureAwait(false); ulong size = 0; foreach (var strm in entries) { size += strm.Location.FileSize; } var section = calc.RVAToSection(rva); var location = new Location(image, offset, rva, va, size, size, section); return(new CLRMetaDataStreamTable(image, location, entries)); } catch (Exception ex) { throw new PortableExecutableImageException(image, "Could not read CLR meta-data streams table from stream.", ex); } }