/// <summary> /// Dispose method /// </summary> /// <param name="disposing"><c>true</c> if called by <see cref="Dispose()"/></param> protected virtual void Dispose(bool disposing) { if (!disposing) { return; } Dispose(peImage); Dispose(stringsStream); Dispose(usStream); Dispose(blobStream); Dispose(guidStream); Dispose(tablesStream); var as2 = allStreams; if (as2 != null) { foreach (var stream in as2.GetSafeEnumerable()) { Dispose(stream); } } peImage = null; cor20Header = null; mdHeader = null; stringsStream = null; usStream = null; blobStream = null; guidStream = null; tablesStream = null; allStreams = null; fieldRidToTypeDefRid = null; methodRidToTypeDefRid = null; typeDefRidToNestedClasses = null; }
/// <summary> /// Constructor /// </summary> /// <param name="peImage">The PE image</param> /// <param name="cor20Header">The .NET header</param> /// <param name="mdHeader">The MD header</param> protected MetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeader mdHeader) { try { this.allStreams = ThreadSafeListCreator.Create <DotNetStream>(); this.peImage = peImage; this.cor20Header = cor20Header; this.mdHeader = mdHeader; } catch { if (peImage != null) { peImage.Dispose(); } throw; } }
/// <summary> /// Create a <see cref="MetaData"/> instance /// </summary> /// <param name="peImage">The PE image</param> /// <param name="verify"><c>true</c> if we should verify that it's a .NET PE file</param> /// <returns>A new <see cref="MetaData"/> instance</returns> internal static MetaData Create(IPEImage peImage, bool verify) { IImageStream cor20HeaderStream = null, mdHeaderStream = null; MetaData md = null; try { var dotNetDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14]; if (dotNetDir.VirtualAddress == 0) { throw new BadImageFormatException(".NET data directory RVA is 0"); } if (dotNetDir.Size < 0x48) { throw new BadImageFormatException(".NET data directory size < 0x48"); } var cor20Header = new ImageCor20Header(cor20HeaderStream = peImage.CreateStream(dotNetDir.VirtualAddress, 0x48), verify); if (cor20Header.MetaData.VirtualAddress == 0) { throw new BadImageFormatException(".NET MetaData RVA is 0"); } if (cor20Header.MetaData.Size < 16) { throw new BadImageFormatException(".NET MetaData size is too small"); } var mdSize = cor20Header.MetaData.Size; var mdRva = cor20Header.MetaData.VirtualAddress; var mdHeader = new MetaDataHeader(mdHeaderStream = peImage.CreateStream(mdRva, mdSize), verify); if (verify) { foreach (var sh in mdHeader.StreamHeaders) { if (sh.Offset + sh.StreamSize < sh.Offset || sh.Offset + sh.StreamSize > mdSize) { throw new BadImageFormatException("Invalid stream header"); } } } switch (GetMetaDataType(mdHeader.StreamHeaders)) { case MetaDataType.Compressed: md = new CompressedMetaData(peImage, cor20Header, mdHeader); break; case MetaDataType.ENC: md = new ENCMetaData(peImage, cor20Header, mdHeader); break; default: throw new BadImageFormatException("No #~ or #- stream found"); } md.Initialize(); return(md); } catch { if (md != null) { md.Dispose(); } throw; } finally { if (cor20HeaderStream != null) { cor20HeaderStream.Dispose(); } if (mdHeaderStream != null) { mdHeaderStream.Dispose(); } } }
/// <inheritdoc/> public ENCMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeader mdHeader) : base(peImage, cor20Header, mdHeader) { }
/// <inheritdoc/> public CompressedMetaData(IPEImage peImage, ImageCor20Header cor20Header, MetaDataHeader mdHeader) : base(peImage, cor20Header, mdHeader) { }