/// <summary>
        /// Gets the raw section data of the image. The sections are saved in
        /// <see cref="origSections"/>.
        /// </summary>
        void CreateRawSections()
        {
            var fileAlignment = peImage.ImageNTHeaders.OptionalHeader.FileAlignment;

            origSections = new List <OrigSection>(peImage.ImageSectionHeaders.Count);

            foreach (var peSection in peImage.ImageSectionHeaders)
            {
                var newSection = new OrigSection(peSection);
                origSections.Add(newSection);
                uint sectionSize = Utils.AlignUp(peSection.SizeOfRawData, fileAlignment);
                newSection.chunk = new BinaryReaderChunk(peImage.CreateStream(peSection.VirtualAddress, sectionSize), peSection.VirtualSize);
            }
        }
        /// <summary>
        /// Initializes MD tables
        /// </summary>
        /// <param name="peImage">The PEImage</param>
        public void Initialize(IPEImage peImage)
        {
            reserved1    = imageStream.ReadUInt32();
            majorVersion = imageStream.ReadByte();
            minorVersion = imageStream.ReadByte();
            flags        = (MDStreamFlags)imageStream.ReadByte();
            log2Rid      = imageStream.ReadByte();
            validMask    = imageStream.ReadUInt64();
            sortedMask   = imageStream.ReadUInt64();

            int maxPresentTables;
            var dnTableSizes = new DotNetTableSizes();
            var tableInfos   = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);

            mdTables = new MDTable[tableInfos.Length];

            ulong valid = validMask;
            var   sizes = new uint[64];

            for (int i = 0; i < 64; valid >>= 1, i++)
            {
                uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
                if (i >= maxPresentTables)
                {
                    rows = 0;
                }
                sizes[i] = rows;
                if (i < mdTables.Length)
                {
                    mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
                }
            }

            if (HasExtraData)
            {
                extraData = imageStream.ReadUInt32();
            }

            dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes);

            var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position;

            foreach (var mdTable in mdTables)
            {
                var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
                mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen);
                var newRva = currentRva + (uint)dataLen;
                if (newRva < currentRva)
                {
                    throw new BadImageFormatException("Too big MD table");
                }
                currentRva = newRva;
            }

            InitializeTables();
        }
Example #3
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="peImage">The PE image</param>
 /// <param name="rsrcReader">Reader for the whole Win32 resources section (usually
 /// the .rsrc section) or <c>null</c> if we should create one from the resource data
 /// directory in the optional header. This instance owns the reader.</param>
 public Win32ResourcesPE(IPEImage peImage, IBinaryReader rsrcReader)
 {
     this.rvaConverter = peImage;
     this.dataReader   = peImage.CreateFullStream();
     if (rsrcReader != null)
     {
         this.rsrcReader = rsrcReader;
     }
     else
     {
         var dataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[2];
         if (dataDir.VirtualAddress != 0 && dataDir.Size != 0)
         {
             this.rsrcReader = peImage.CreateStream(dataDir.VirtualAddress, dataDir.Size);
         }
         else
         {
             this.rsrcReader = MemoryImageStream.CreateEmpty();
         }
     }
     Initialize();
 }
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="peImage">The PE image</param>
		/// <param name="rsrcReader">Reader for the whole Win32 resources section (usually
		/// the .rsrc section) or <c>null</c> if we should create one from the resource data
		/// directory in the optional header. This instance owns the reader.</param>
		public Win32ResourcesPE(IPEImage peImage, IBinaryReader rsrcReader) {
			this.rvaConverter = peImage;
			this.dataReader = peImage.CreateFullStream();
			if (rsrcReader != null)
				this.rsrcReader = rsrcReader;
			else {
				var dataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[2];
				if (dataDir.VirtualAddress != 0 && dataDir.Size != 0)
					this.rsrcReader = peImage.CreateStream(dataDir.VirtualAddress, dataDir.Size);
				else
					this.rsrcReader = MemoryImageStream.CreateEmpty();
			}
			Initialize();
		}
		/// <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();
			}
		}
Example #6
0
 /// <summary>
 /// Creates a stream to access part of the PE image from <paramref name="rva"/>
 /// with length <paramref name="length"/>
 /// </summary>
 /// <param name="self">this</param>
 /// <param name="rva">RVA</param>
 /// <param name="length">Length of data</param>
 /// <returns>A new stream</returns>
 /// <exception cref="ArgumentOutOfRangeException">If any arg is invalid</exception>
 public static IImageStream CreateStream(this IPEImage self, RVA rva, long length)
 {
     return(self.CreateStream(self.ToFileOffset(rva), length));
 }
        /// <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();
                }
            }
        }
		/// <summary>
		/// Initializes MD tables
		/// </summary>
		/// <param name="peImage">The PEImage</param>
		public void Initialize(IPEImage peImage) {
			if (initialized)
				throw new Exception("Initialize() has already been called");
			initialized = true;

			reserved1 = imageStream.ReadUInt32();
			majorVersion = imageStream.ReadByte();
			minorVersion = imageStream.ReadByte();
			flags = (MDStreamFlags)imageStream.ReadByte();
			log2Rid = imageStream.ReadByte();
			validMask = imageStream.ReadUInt64();
			sortedMask = imageStream.ReadUInt64();

			int maxPresentTables;
			var dnTableSizes = new DotNetTableSizes();
			var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);
			mdTables = new MDTable[tableInfos.Length];

			ulong valid = validMask;
			var sizes = new uint[64];
			for (int i = 0; i < 64; valid >>= 1, i++) {
				uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
				if (i >= maxPresentTables)
					rows = 0;
				sizes[i] = rows;
				if (i < mdTables.Length)
					mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
			}

			if (HasExtraData)
				extraData = imageStream.ReadUInt32();

			dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes);

			var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position;
			foreach (var mdTable in mdTables) {
				var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
				mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen);
				var newRva = currentRva + (uint)dataLen;
				if (newRva < currentRva)
					throw new BadImageFormatException("Too big MD table");
				currentRva = newRva;
			}

			InitializeTables();
		}
Example #9
0
 public static IImageStream CreateStream(this IPEImage image, FileSection section)
 {
     return(image.CreateStream(section.StartOffset, section.EndOffset - section.StartOffset));
 }