/// <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;
            }
        }
Esempio n. 2
0
		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);
		}
Esempio n. 3
0
 void Initialize(IPEImage peImage)
 {
     this.peImage = peImage;
     Reader       = peImage.CreateReader();
 }