Exemplo n.º 1
0
        /// <summary>
        /// Loads the header from the reader.
        /// </summary>
        /// <param name="reader">The reader.</param>
        public void Read(EndianAwareBinaryReader reader)
        {
            Magic = reader.ReadUInt16();
            if (IMAGE_OPTIONAL_HEADER_MAGIC != Magic)
                throw new BadImageFormatException();

            MajorLinkerVersion = reader.ReadByte();
            MinorLinkerVersion = reader.ReadByte();
            SizeOfCode = reader.ReadUInt32();
            SizeOfInitializedData = reader.ReadUInt32();
            SizeOfUninitializedData = reader.ReadUInt32();
            AddressOfEntryPoint = reader.ReadUInt32();
            BaseOfCode = reader.ReadUInt32();
            BaseOfData = reader.ReadUInt32();

            ImageBase = reader.ReadUInt32();
            SectionAlignment = reader.ReadUInt32();
            FileAlignment = reader.ReadUInt32();
            MajorOperatingSystemVersion = reader.ReadUInt16();
            MinorOperatingSystemVersion = reader.ReadUInt16();
            MajorImageVersion = reader.ReadUInt16();
            MinorImageVersion = reader.ReadUInt16();
            MajorSubsystemVersion = reader.ReadUInt16();
            MinorSubsystemVersion = reader.ReadUInt16();
            Win32VersionValue = reader.ReadUInt32();
            SizeOfImage = reader.ReadUInt32();
            SizeOfHeaders = reader.ReadUInt32();
            CheckSum = reader.ReadUInt32();
            Subsystem = reader.ReadUInt16();
            DllCharacteristics = reader.ReadUInt16();
            SizeOfStackReserve = reader.ReadUInt32();
            SizeOfStackCommit = reader.ReadUInt32();
            SizeOfHeapReserve = reader.ReadUInt32();
            SizeOfHeapCommit = reader.ReadUInt32();
            LoaderFlags = reader.ReadUInt32();
            NumberOfRvaAndSizes = reader.ReadUInt32();

            DataDirectory = new ImageDataDirectory[NumberOfRvaAndSizes];
            for (int i = 0; i < NumberOfRvaAndSizes; i++)
            {
                DataDirectory[i].Read(reader);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        public MethodHeader(EndianAwareBinaryReader reader)
        {
            Clauses = new List<ExceptionHandlingClause>();

            // Read first byte
            Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (Flags & MethodFlags.HeaderMask)
            {
                case MethodFlags.TinyFormat:
                    CodeSize = ((int)(Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                    Flags &= MethodFlags.HeaderMask;
                    break;

                case MethodFlags.FatFormat:
                    // Read second byte of flags
                    Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)Flags);

                    if (MethodFlags.ValidHeader != (Flags & MethodFlags.HeaderSizeMask))
                        throw new CompilerException("Invalid method ");

                    MaxStack = reader.ReadUInt16();
                    CodeSize = reader.ReadInt32();
                    LocalVarSigTok = new Token(reader.ReadUInt32()); // ReadStandAloneSigRow
                    break;

                default:
                    throw new CompilerException("Invalid method header");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (Flags & MethodFlags.MoreSections))
                return;

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + CodeSize;
            if (0 != (dataSectPos & 3))
                dataSectPos += (4 - (dataSectPos % 4));
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int length;
                int blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), "Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    Clauses.Add(clause);
                }
            }
            while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;
        }