Beispiel #1
0
        /// <summary>
        /// Create a standalone portable PDB <see cref="MetaData"/> instance
        /// </summary>
        /// <param name="mdStream">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="MetaData"/> instance</returns>
        internal static MetaData CreateStandalonePortablePDB(IImageStream mdStream, bool verify)
        {
            MetaData md = null;

            try {
                var mdHeader = new MetaDataHeader(mdStream, verify);
                if (verify)
                {
                    foreach (var sh in mdHeader.StreamHeaders)
                    {
                        if (sh.Offset + sh.StreamSize < sh.Offset || sh.Offset + sh.StreamSize > mdStream.Length)
                        {
                            throw new BadImageFormatException("Invalid stream header");
                        }
                    }
                }

                switch (GetMetaDataType(mdHeader.StreamHeaders))
                {
                case MetaDataType.Compressed:
                    md = new CompressedMetaData(mdHeader, true);
                    break;

                case MetaDataType.ENC:
                    md = new ENCMetaData(mdHeader, true);
                    break;

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

                return(md);
            }
            catch {
                if (md != null)
                {
                    md.Dispose();
                }
                throw;
            }
        }
		/// <summary>
		/// Create a <see cref="DotNetFile"/> 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="DotNetFile"/> instance</returns>
		public static DotNetFile Load(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 new DotNetFile(md);
			}
			catch {
				if (md != null)
					md.Dispose();
				throw;
			}
			finally {
				if (cor20HeaderStream != null)
					cor20HeaderStream.Dispose();
				if (mdHeaderStream != null)
					mdHeaderStream.Dispose();
			}
		}
        /// <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();
                }
            }
        }