/// <summary> /// Create a <see cref="MetadataBase"/> 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="MetadataBase"/> instance</returns> static MetadataBase Create(IPEImage peImage, bool verify) { MetadataBase md = null; try { var dotNetDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[14]; // Mono doesn't check that the Size field is >= 0x48 if (dotNetDir.VirtualAddress == 0) { throw new BadImageFormatException(".NET data directory RVA is 0"); } var cor20HeaderReader = peImage.CreateReader(dotNetDir.VirtualAddress, 0x48); var cor20Header = new ImageCor20Header(ref cor20HeaderReader, verify); if (cor20Header.Metadata.VirtualAddress == 0) { throw new BadImageFormatException(".NET metadata RVA is 0"); } var mdRva = cor20Header.Metadata.VirtualAddress; // Don't use the size field, Mono ignores it. Create a reader that can read to EOF. var mdHeaderReader = peImage.CreateReader(mdRva); var mdHeader = new MetadataHeader(ref mdHeaderReader, verify); if (verify) { foreach (var sh in mdHeader.StreamHeaders) { if ((ulong)sh.Offset + sh.StreamSize > mdHeaderReader.EndOffset) { 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(null); return(md); } catch { if (md != null) { md.Dispose(); } throw; } }
HexBuffer GetOrCreate(IPEImage peImage) { var filename = GetFullPath(peImage.Filename); HexBuffer? buffer; lock (lockObj) { buffer = TryGet_NoLock(filename); if (buffer is not null) return buffer; buffer = hexBufferFactoryService.Create(peImage.CreateReader().ToArray(), filename, hexBufferFactoryService.DefaultFileTags); filenameToBuffer[filename] = new WeakReference(buffer); } return NotifyBufferCreated(buffer); }
void Initialize(IPEImage peImage) { this.peImage = peImage; Reader = peImage.CreateReader(); }