public void GetResources() { int resourceTableIdx = (int)CoffImageDirectoriesIndex.ResourceTable; CoffImageDataDirectory[] directories = GetDataDirectory(); if (directories.Length <= resourceTableIdx) { throw new PEResourceException("The PE Image does not contain a resource directory."); } CoffImageDataDirectory resourceDirectory = directories[resourceTableIdx]; if (resourceDirectory.VirtualAddress == 0 || resourceDirectory.Size == 0) { throw new PEResourceException("The PE Image does not contain any resource data."); } ////////////////////////////////////////// SectionTableEntry?sectionTemp; UInt32 fileOffset = _pe.RvaToFileOffset(resourceDirectory.VirtualAddress, out sectionTemp); if (fileOffset == 0 && sectionTemp == null) { throw new PEResourceException("The PE Image's resource directory does not exist within a section."); } SectionTableEntry section = sectionTemp.Value; // Ensure the resource section is the same size (and address) as the resource directory entry says if (resourceDirectory.Size != section.VirtualSize || resourceDirectory.VirtualAddress != section.VirtualAddress) { throw new PEResourceException("The PE Image's declared resource directory does not coincide with the size and location of the .rsrc section."); } // Apparently SizeOfRawData can be smaller than VirtualSize for .rsrc sections, according to the spec the rest should be filled with zeros // So I hope this doesn't affect the parsing of the actual data... //////////////////////////////////////////////////// // Read the Resource Directories _fs.Seek(fileOffset, SeekOrigin.Begin); BinaryReader rdr = new BinaryReader(_fs); ResourceDirectoryTable rootTable = new ResourceDirectoryTable(_pe, rdr); }
/// <summary>Gets the SectionTableEntry that contains the specified RVA.</summary> private SectionTableEntry?GetSectionEntry(UInt32 rva) { for (int i = 0; i < this.SectionTable.Length; i++) { SectionTableEntry sectionEntry = this.SectionTable[i]; UInt32 maxSize = Math.Max(sectionEntry.VirtualSize, sectionEntry.SizeOfRawData); // this also solves the Watcom Linker issue where VirtualSize == 0 // Is the RVA within this section? if (rva >= sectionEntry.VirtualAddress && rva < sectionEntry.VirtualAddress + maxSize) { return(sectionEntry); } } return(null); }
private void Load(Stream stream) { var rdr = new BinaryReader(stream); //////////////////////////////////// // The DOS Stub and PE Offset marker DosHeader = new DosHeader(rdr); PEOffset = DosHeader.NewExeHeaderAddress; // this is at 0x3C rdr.BaseStream.Seek(PEOffset, SeekOrigin.Begin); //////////////////////////////////// // The COFF File Header PESignature = rdr.ReadBytes(4); if (!IsPESignature(PESignature)) { throw new FormatException("The specified file does not contain a PE signature."); } CoffFileHeader = new CoffFileHeader(rdr); var offsetEndOfCoffFileHeader = rdr.BaseStream.Position; //////////////////////////////////// // The Optional Header var magic = (PE32Magic)rdr.ReadUInt16(); switch (magic) { case PE32Magic.PE32: // Ensure the Optional Header is big enough for the minimum amount of data // Standard fields: 28 bytes // Windows fields: 68 bytes // Total: 92 bytes if (CoffFileHeader.SizeOfOptionalHeader < 96) { var msg = string.Format( "The specified file's declared Optional Header size of {0} bytes is smaller than the minimum of 96 required bytes.", CoffFileHeader.SizeOfOptionalHeader ); throw new FormatException(msg); } OptionalHeader32 = new CoffOptionalHeader32(magic, rdr); break; case PE32Magic.PE32Plus: // Standard fields: 24 bytes // Windows fields: 88 bytes // Total: 112 bytes if (CoffFileHeader.SizeOfOptionalHeader < 112) { var msg = string.Format( "The specified file's declared Optional Header size of {0} bytes is smaller than the minimum of 112 required bytes.", CoffFileHeader.SizeOfOptionalHeader ); throw new FormatException(msg); } OptionalHeader32Plus = new CoffOptionalHeader32Plus(magic, rdr); break; case PE32Magic.RomImage: default: OptionalHeader = rdr.ReadBytes(CoffFileHeader.SizeOfOptionalHeader); break; } var offsetEndOfOptionalHeader = rdr.BaseStream.Position; // by now we're at the end of the Optional Header, but let's make sure if (offsetEndOfOptionalHeader != offsetEndOfCoffFileHeader + CoffFileHeader.SizeOfOptionalHeader) { // error condition } /////////////////////////////// // The Section Table SectionTable = new SectionTableEntry[CoffFileHeader.NofSections]; for (var i = 0; i < SectionTable.Length; i++) { SectionTable[i] = new SectionTableEntry(rdr); } }