示例#1
0
        /// <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 is null))
                {
                    md.Dispose();
                }
                throw;
            }
        }
示例#2
0
        /// <summary>
        /// Create a standalone portable PDB <see cref="MetadataBase"/> instance
        /// </summary>
        /// <param name="mdReaderFactory">Metadata stream</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>
        internal static MetadataBase CreateStandalonePortablePDB(DataReaderFactory mdReaderFactory, bool verify)
        {
            const CLRRuntimeReaderKind runtime = CLRRuntimeReaderKind.CLR;
            MetadataBase md = null;

            try {
                var reader   = mdReaderFactory.CreateReader();
                var mdHeader = new MetadataHeader(ref reader, runtime, verify);
                if (verify)
                {
                    foreach (var sh in mdHeader.StreamHeaders)
                    {
                        if (sh.Offset + sh.StreamSize < sh.Offset || sh.Offset + sh.StreamSize > reader.Length)
                        {
                            throw new BadImageFormatException("Invalid stream header");
                        }
                    }
                }

                switch (GetMetadataType(mdHeader.StreamHeaders, runtime))
                {
                case MetadataType.Compressed:
                    md = new CompressedMetadata(mdHeader, true, runtime);
                    break;

                case MetadataType.ENC:
                    md = new ENCMetadata(mdHeader, true, runtime);
                    break;

                default:
                    throw new BadImageFormatException("No #~ or #- stream found");
                }
                md.Initialize(mdReaderFactory);

                return(md);
            }
            catch {
                md?.Dispose();
                throw;
            }
        }