Esempio n. 1
0
        public NEFile(String fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 0x400, FileOptions.None)) {
                BinaryReader rdr = new BinaryReader(fs);

                ///////////////////////////////
                // DOS Header

                DosHeader = new DosHeader(rdr);

                // The NE documentation states that if the UInt16 at 0x18 in the DOS header is 0x40, then the UInt16 at 0x3C contains the byte offset (from the beginning of the file) to the segmented header (i.e. 'NE')

                ///////////////////////////////
                // NE Offset

                if (DosHeader.RelocationTableOffset != 0x40)
                {
                    throw new FormatException("The specified file does not contain an NE segment pointer.");
                }

                rdr.BaseStream.Seek(0x3C, SeekOrigin.Begin);

                NEOffset = rdr.ReadUInt16();

                rdr.BaseStream.Seek(NEOffset, SeekOrigin.Begin);

                ///////////////////////////////
                // NE Header

                NEHeader = new NEHeader(rdr);

                ///////////////////////////////
                // NE Segment Table

                long bytesWasted1 = (NEOffset + NEHeader.SegmentTableOffset) - rdr.BaseStream.Position;

                rdr.BaseStream.Seek(NEOffset + NEHeader.SegmentTableOffset, SeekOrigin.Begin);

                SegmentTable = new NESegmentTableEntry[NEHeader.SegmentTableCount];
                for (int i = 0; i < NEHeader.SegmentTableCount; i++)
                {
                    SegmentTable[i].Offset            = rdr.ReadUInt16();
                    SegmentTable[i].Size              = rdr.ReadUInt16();
                    SegmentTable[i].Type              = (NESegmentType)rdr.ReadUInt16();
                    SegmentTable[i].MinimumAllocation = rdr.ReadUInt16();
                }

                ///////////////////////////////
                // Resource Table

                long bytesWasted2 = (NEOffset + NEHeader.ResourceTableOffset) - rdr.BaseStream.Position;

                rdr.BaseStream.Seek(NEOffset + NEHeader.ResourceTableOffset, SeekOrigin.Begin);

                ResourceTable = new NEResourceTable(rdr);

                ///////////////////////////////
                // Resident Name Table

                ///////////////////////////////
                // Module-Reference Table

                ///////////////////////////////
                // Imported-Name Table

                ///////////////////////////////
                // Entry Table

                ///////////////////////////////
                // Non-Resident Name Table

                ///////////////////////////////
                // Per-Segment Data
            }
        }
Esempio n. 2
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);
            }
        }