Exemple #1
0
        /// <summary>
        /// Loads a DOS MZ executable file from disk.
        /// </summary>
        /// <param name="fileName">Name of the file to open.</param>
        public MZFile(string fileName)
        {
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }

            using (FileStream stream = new FileStream(fileName,
                                                      FileMode.Open, FileAccess.Read, FileShare.Read))
                using (BinaryReader reader = new BinaryReader(stream))
                {
                    // Read file header.
                    header              = new MZHeader();
                    header.Signature    = reader.ReadUInt16();
                    header.LastPageSize = reader.ReadUInt16();
                    header.PageCount    = reader.ReadUInt16();
                    header.RelocCount   = reader.ReadUInt16();
                    header.HeaderSize   = reader.ReadUInt16();
                    header.MinAlloc     = reader.ReadUInt16();
                    header.MaxAlloc     = reader.ReadUInt16();
                    header.InitialSS    = reader.ReadUInt16();
                    header.InitialSP    = reader.ReadUInt16();
                    header.Checksum     = reader.ReadUInt16();
                    header.InitialIP    = reader.ReadUInt16();
                    header.InitialCS    = reader.ReadUInt16();
                    header.RelocOff     = reader.ReadUInt16();
                    header.Overlay      = reader.ReadUInt16();

                    // Verify signature. Both 'MZ' and 'ZM' are allowed.
                    if (!(header.Signature == 0x5A4D || header.Signature == 0x4D5A))
                    {
                        throw new InvalidDataException("Signature mismatch.");
                    }

                    // Calculate the stated size of the executable.
                    if (header.PageCount <= 0)
                    {
                        throw new InvalidDataException("The PageCount field must be positive.");
                    }
                    int fileSize = header.PageCount * 512 -
                                   (header.LastPageSize > 0 ? 512 - header.LastPageSize : 0);

                    // Make sure the stated file size is within the actual file size.
                    if (fileSize > stream.Length)
                    {
                        throw new InvalidDataException("The stated file size is larger than the actual file size.");
                    }

                    // Validate the header size.
                    int headerSize = header.HeaderSize * 16;
                    if (headerSize < 28 || headerSize > fileSize)
                    {
                        throw new InvalidDataException("The stated header size is invalid.");
                    }

                    // Make sure the relocation table is within the header.
                    if (header.RelocOff < 28 ||
                        header.RelocOff + header.RelocCount * 4 > headerSize)
                    {
                        throw new InvalidDataException("The relocation table location is invalid.");
                    }

                    // Load relocation table.
                    relocationTable = new FarPointer[header.RelocCount];
                    stream.Seek(header.RelocOff, SeekOrigin.Begin);
                    for (int i = 0; i < header.RelocCount; i++)
                    {
                        UInt16 off = reader.ReadUInt16();
                        UInt16 seg = reader.ReadUInt16();
                        relocationTable[i] = new FarPointer(seg, off);
                    }

                    // Load the whole image into memory.
                    int imageSize = fileSize - headerSize;
                    stream.Seek(headerSize, SeekOrigin.Begin);
                    image = new byte[imageSize];
                    stream.Read(image, 0, image.Length);
                }
        }
Exemple #2
0
        /// <summary>
        /// Loads a DOS MZ executable file from disk.
        /// </summary>
        /// <param name="fileName">Name of the file to open.</param>
        public MZFile(string fileName)
        {
            if (fileName == null)
                throw new ArgumentNullException("fileName");

            using (FileStream stream = new FileStream(fileName,
                FileMode.Open, FileAccess.Read, FileShare.Read))
            using (BinaryReader reader = new BinaryReader(stream))
            {
                // Read file header.
                header = new MZHeader();
                header.Signature = reader.ReadUInt16();
                header.LastPageSize = reader.ReadUInt16();
                header.PageCount = reader.ReadUInt16();
                header.RelocCount = reader.ReadUInt16();
                header.HeaderSize = reader.ReadUInt16();
                header.MinAlloc = reader.ReadUInt16();
                header.MaxAlloc = reader.ReadUInt16();
                header.InitialSS = reader.ReadUInt16();
                header.InitialSP = reader.ReadUInt16();
                header.Checksum = reader.ReadUInt16();
                header.InitialIP = reader.ReadUInt16();
                header.InitialCS = reader.ReadUInt16();
                header.RelocOff = reader.ReadUInt16();
                header.Overlay = reader.ReadUInt16();

                // Verify signature. Both 'MZ' and 'ZM' are allowed.
                if (!(header.Signature == 0x5A4D || header.Signature == 0x4D5A))
                    throw new InvalidDataException("Signature mismatch.");

                // Calculate the stated size of the executable.
                if (header.PageCount <= 0)
                    throw new InvalidDataException("The PageCount field must be positive.");
                int fileSize = header.PageCount * 512 -
                    (header.LastPageSize > 0 ? 512 - header.LastPageSize : 0);

                // Make sure the stated file size is within the actual file size.
                if (fileSize > stream.Length)
                    throw new InvalidDataException("The stated file size is larger than the actual file size.");

                // Validate the header size.
                int headerSize = header.HeaderSize * 16;
                if (headerSize < 28 || headerSize > fileSize)
                    throw new InvalidDataException("The stated header size is invalid.");

                // Make sure the relocation table is within the header.
                if (header.RelocOff < 28 ||
                    header.RelocOff + header.RelocCount * 4 > headerSize)
                {
                    throw new InvalidDataException("The relocation table location is invalid.");
                }

                // Load relocation table.
                relocationTable = new FarPointer[header.RelocCount];
                stream.Seek(header.RelocOff, SeekOrigin.Begin);
                for (int i = 0; i < header.RelocCount; i++)
                {
                    UInt16 off = reader.ReadUInt16();
                    UInt16 seg = reader.ReadUInt16();
                    relocationTable[i] = new FarPointer(seg, off);
                }

                // Load the whole image into memory.
                int imageSize = fileSize - headerSize;
                stream.Seek(headerSize, SeekOrigin.Begin);
                image = new byte[imageSize];
                stream.Read(image, 0, image.Length);
            }
        }