internal MetaDataRoot(ref BinaryReader reader, ref byte[] buf, ulong startPos)
    {
        uint      i, offset;
        ulong     curPos = startPos;
        Exception toBeThrown;

        reader.BaseStream.Seek((long)curPos, SeekOrigin.Begin);

        m_signature = reader.ReadUInt32();
                #if DEBUG0
        Console.Write("metadata m_signature: ");
        Console.Write((char)(m_signature & 0xff));
        Console.Write((char)((m_signature & 0xff00) >> 8));
        Console.Write((char)((m_signature & 0xff0000) >> 16));
        Console.WriteLine((char)((m_signature & 0xff000000) >> 24) + Environment.NewLine);
                #endif
        if (m_signature != METADATA_SIGNATURE)
        {
            toBeThrown = new InvalidFileFormat("Invalid CIL binary file format.");
            throw toBeThrown;
        }

        m_majorVersion  = reader.ReadUInt16();
        m_minorVersion  = reader.ReadUInt16();
        m_extraData     = reader.ReadUInt32();
        m_versionStrLen = reader.ReadUInt32();
        curPos         += (ulong)16;

        m_versionStr = Encoding.ASCII.GetString(buf, (int)curPos, (int)m_versionStrLen);
        curPos      += (ulong)m_versionStrLen;
        reader.BaseStream.Seek(m_versionStrLen, SeekOrigin.Current);

        m_flags      = reader.ReadByte();
        m_pad        = reader.ReadByte();
        m_numStreams = reader.ReadUInt16();
        curPos      += (ulong)4;

        // Read each stream header.
        m_streamHeaders = new StreamHeader[m_numStreams];
        for (i = 0; i < m_numStreams; i++)
        {
            m_streamHeaders[i].offset = reader.ReadUInt32();
            m_streamHeaders[i].size   = reader.ReadUInt32();

            curPos += 8;

            // Read the stream name.
            m_streamHeaders[i].name = "";
            for ( ; ; curPos++)
            {
                m_streamHeaders[i].name += (char)buf[curPos];
                if (buf[curPos] == '\0')
                {
                    curPos++;
                    break;
                }
            }

            // Read until the length of the stream name is a multiple of 4.
            offset = (uint)m_streamHeaders[i].name.Length;
            for ( ; offset % 4 != 0; curPos++, offset++)
            {
            }
            ;

            reader.BaseStream.Seek(offset, SeekOrigin.Current);
        }
    }
Beispiel #2
0
    internal NTHeader(ref BinaryReader reader)
    {
        Exception toBeThrown;

        m_PESignature = reader.ReadUInt32();
        if (m_PESignature != PE_SIGNATURE)
        {
            toBeThrown = new InvalidFileFormat("Invalid CIL binary file format.");
            throw toBeThrown;
        }

        // COFF Header
        m_Machine              = reader.ReadUInt16();
        m_NumberOfSections     = reader.ReadUInt16();
        m_TimeDateStamp        = reader.ReadUInt32();
        m_PointerToSymbolTable = reader.ReadUInt32();
        m_NumberOfSymbols      = reader.ReadUInt32();
        m_OptionalHeaderSize   = reader.ReadUInt16();
        m_Characteristics      = reader.ReadUInt16();

        if (m_OptionalHeaderSize == 0)
        {
            toBeThrown = new InvalidFileFormat("Invalid CIL binary file format.");
            throw toBeThrown;
        }

        // Optional Header - Standard fields
        m_Magic = reader.ReadUInt16();
        if (m_Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
        {
            toBeThrown = new InvalidFileFormat("Invalid CIL binary file format.");
            throw toBeThrown;
        }

        m_MajorLinkerVersion   = reader.ReadByte();
        m_MinorLinkerVersion   = reader.ReadByte();
        m_CodeSize             = reader.ReadUInt32();
        m_InitializeDataSize   = reader.ReadUInt32();
        m_UninitializeDataSize = reader.ReadUInt32();
        m_EntryPointRVA        = reader.ReadUInt32();
        m_BaseOfCode           = reader.ReadUInt32();
        m_BaseOfData           = reader.ReadUInt32();

        // Optional Header - NT-specific fields
        m_ImageBase                   = reader.ReadUInt32();
        m_SectionAlignment            = reader.ReadUInt32();
        m_FileAlignment               = reader.ReadUInt32();
        m_MajorOperatingSystemVersion = reader.ReadUInt16();
        m_MinorOperatingSystemVersion = reader.ReadUInt16();
        m_MajorImageVersion           = reader.ReadUInt16();
        m_MinorImageVersion           = reader.ReadUInt16();
        m_MajorSubsystemVersion       = reader.ReadUInt16();
        m_MinorSubsystemVersion       = reader.ReadUInt16();
        m_Reserved                = reader.ReadUInt32();
        m_ImageSize               = reader.ReadUInt32();
        m_HeaderSize              = reader.ReadUInt32();
        m_FileCheckSum            = reader.ReadUInt32();
        m_Subsystem               = reader.ReadUInt16();
        m_DLLFlags                = reader.ReadUInt16();
        m_StackReserveSize        = reader.ReadUInt32();
        m_StackCommitSize         = reader.ReadUInt32();
        m_HeapReserveSize         = reader.ReadUInt32();
        m_HeapCommitSize          = reader.ReadUInt32();
        m_LoaderFlags             = reader.ReadUInt32();
        m_NumberOfDataDirectories = reader.ReadUInt32();

        // The number of data directories in the remainder of the optional header is always 16.
        if (m_NumberOfDataDirectories != 16)
        {
            toBeThrown = new InvalidFileFormat("Invalid CIL binary file format.");
            throw toBeThrown;
        }

        // Optional Header - Data directories
        m_DataDirectory = new ImageDataDirectory[m_NumberOfDataDirectories];
        for (int i = 0; i < m_NumberOfDataDirectories; i++)
        {
            m_DataDirectory[i].RVA  = reader.ReadUInt32();
            m_DataDirectory[i].Size = reader.ReadUInt32();
        }
    }
Beispiel #3
0
    internal MetaDataRoot m_mdr;                                // MetaData Root table

    /*********************************************************************************************************************
    *	1) Parse the MetaData Root table.
    *
    *	2) Initialize the various heaps.
    *
    *	3) Initialize "m_oldNameHash", "m_classTree", and "m_freeSpaceList".
    *
    *	4) Initialize the various BitArrays.
    *
    *	5) Set the total numbers of the elements (types, methods, fields, properties, events, and parameters).
    *********************************************************************************************************************/
    internal MetaData(ref byte[] buf)
    {
        int       i, ptHeapIndex = -1;
        Exception toBeThrown;

        m_buffer = buf;

        // Ok.  Now we can build a reader and a writer over the memory m_buffer.
        MemoryStream memStream = new MemoryStream(m_buffer);
        BinaryReader reader    = new BinaryReader(memStream);
        BinaryWriter writer    = new BinaryWriter(memStream);

        AllHeaders all = new AllHeaders(ref reader);
        NTHeader   nth = all.m_ntHeader;

        SectionHeader[] sh = all.m_sectionHeaders;

                #if DEBUG0
        Console.WriteLine("Runtime Header Data Directory");
        Console.WriteLine("rva: " + nth.m_DataDirectory[14].RVA + "; size: " + nth.m_DataDirectory[14].Size + Environment.NewLine);
        Console.WriteLine("offset to MetaData section: " + (long)(nth.m_DataDirectory[14].RVA + 8));
                #endif

        // Read the RVA of the physical MetaData section from the Runtime Header Data Directory.
        reader.BaseStream.Seek((long)(nth.m_DataDirectory[14].RVA + 8), SeekOrigin.Begin);
        m_startPos = reader.ReadUInt64();

        // Theoretically, startPos can be 64 bit long, but in practice, 32 bits are enough.
        // TODO : Check the docs.  The following assertion will fail.
        // Debug.Assert((startPos >> 32) == 0);
        m_startPos = m_startPos & 0xffffffff;                                                   // use the least significant 4 bytes as the offset

        m_mdr = new MetaDataRoot(ref reader, ref m_buffer, m_startPos);

        // We need to initialize the #Strings heap and the #Blob heap before dealing with the #~ heap.
        for (i = 0; i < m_mdr.m_numStreams; i++)
        {
            if (m_mdr.m_streamHeaders[i].name.Equals("#Strings\0"))
            {
                m_strHeap = new StringHeap(ref m_buffer, m_startPos + m_mdr.m_streamHeaders[i].offset, m_mdr.m_streamHeaders[i].size);
            }

            else if (m_mdr.m_streamHeaders[i].name.Equals("#Blob\0"))
            {
                m_blobHeap = new BlobHeap(ref m_buffer, m_startPos + m_mdr.m_streamHeaders[i].offset, m_mdr.m_streamHeaders[i].size);
            }

            else if (m_mdr.m_streamHeaders[i].name.Equals("#~\0") || m_mdr.m_streamHeaders[i].name.Equals("#-\0"))
            {
                ptHeapIndex = i;
            }
        }

        if (ptHeapIndex != -1)
        {
            m_heap = new PTHeap(ref reader, ref writer, ref m_strHeap, m_startPos + m_mdr.m_streamHeaders[ptHeapIndex].offset);
        }
        else
        {
            toBeThrown = new InvalidFileFormat("Invalid CIL binary file format.");
            throw toBeThrown;
        }
    }