/// <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(); }
/// <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(); } }
/// <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(); }
public static IImageStream CreateStream(this IPEImage image, FileSection section) { return(image.CreateStream(section.StartOffset, section.EndOffset - section.StartOffset)); }