示例#1
0
        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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        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);
            }
        }