Example #1
0
        private NativeParser GetParserForBucket(uint bucket, out uint endOffset)
        {
            uint start, end;

            if (_entryIndexSize == 0)
            {
                int bucketOffset = (int)(_baseOffset + bucket);
                start = NativeReader.ReadByte(_image, ref bucketOffset);
                end   = NativeReader.ReadByte(_image, ref bucketOffset);
            }
            else if (_entryIndexSize == 1)
            {
                int bucketOffset = (int)(_baseOffset + 2 * bucket);
                start = NativeReader.ReadUInt16(_image, ref bucketOffset);
                end   = NativeReader.ReadUInt16(_image, ref bucketOffset);
            }
            else
            {
                int bucketOffset = (int)(_baseOffset + 4 * bucket);
                start = NativeReader.ReadUInt32(_image, ref bucketOffset);
                end   = NativeReader.ReadUInt32(_image, ref bucketOffset);
            }

            endOffset = end + _baseOffset;
            return(new NativeParser(_image, _baseOffset + start));
        }
Example #2
0
        public UnwindInfo(byte[] image, int offset)
        {
            byte versionAndFlags = NativeReader.ReadByte(image, ref offset);

            Version            = (byte)(versionAndFlags & 7);
            Flags              = (byte)(versionAndFlags >> 3);
            SizeOfProlog       = NativeReader.ReadByte(image, ref offset);
            CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset);
            byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset);

            FrameRegister = (byte)(frameRegisterAndOffset & 15);
            FrameOffset   = (byte)(frameRegisterAndOffset >> 4);

            UnwindCode = new UnwindCode[CountOfUnwindCodes];
            for (int i = 0; i < CountOfUnwindCodes; i++)
            {
                UnwindCode[i] = new UnwindCode(image, ref offset);
            }

            PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset);

            Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode;
            int alignmentPad = ((Size + sizeof(int) - 1) & ~(sizeof(int) - 1)) - Size;

            Size += (alignmentPad + sizeof(uint));
        }
Example #3
0
        internal override void DumpSectionContents(R2RSection section, XmlNode parentNode)
        {
            XmlNode contentsNode = XmlDocument.CreateNode("element", "Contents", "");

            parentNode.AppendChild(contentsNode);

            switch (section.Type)
            {
            case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
                int availableTypesId = 0;
                foreach (string name in _r2r.AvailableTypes)
                {
                    AddXMLNode("AvailableType", name, contentsNode, $"{availableTypesId++}");
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS:
                int rtfOffset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int rtfEndOffset = rtfOffset + section.Size;
                int rtfIndex     = 0;
                while (rtfOffset < rtfEndOffset)
                {
                    uint rva = NativeReader.ReadUInt32(_r2r.Image, ref rtfOffset);
                    AddXMLNode($"id{rtfIndex}", $"0x{rva:X8}", contentsNode, $"{rtfIndex}");
                    rtfIndex++;
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER:
                AddXMLNode("CompilerIdentifier", _r2r.CompilerIdentifier, contentsNode);
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
                foreach (R2RImportSection importSection in _r2r.ImportSections)
                {
                    Serialize(importSection, contentsNode);
                    if (_raw && importSection.Entries.Count != 0)
                    {
                        if (importSection.SectionRVA != 0)
                        {
                            DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize, contentsNode, "SectionBytes");
                        }
                        if (importSection.SignatureRVA != 0)
                        {
                            DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int), contentsNode, "SignatureBytes");
                        }
                        if (importSection.AuxiliaryDataRVA != 0)
                        {
                            DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size, contentsNode, "AuxiliaryDataBytes");
                        }
                    }
                    foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
                    {
                        Serialize(entry, contentsNode);
                    }
                }
                break;
            }
        }
Example #4
0
        /// <summary>
        /// Initializes the fields of the R2RHeader
        /// </summary>
        /// <param name="image">PE image</param>
        /// <param name="rva">Relative virtual address of the ReadyToRun header</param>
        /// <param name="curOffset">Index in the image byte array to the start of the ReadyToRun header</param>
        /// <exception cref="BadImageFormatException">The signature must be 0x00525452</exception>
        public R2RHeader(byte[] image, int rva, int curOffset)
        {
            RelativeVirtualAddress = rva;
            int startOffset = curOffset;

            byte[] signature = new byte[sizeof(uint)];
            Array.Copy(image, curOffset, signature, 0, sizeof(uint));
            SignatureString = System.Text.Encoding.UTF8.GetString(signature);
            Signature       = NativeReader.ReadUInt32(image, ref curOffset);
            if (Signature != READYTORUN_SIGNATURE)
            {
                throw new System.BadImageFormatException("Incorrect R2R header signature");
            }

            MajorVersion = NativeReader.ReadUInt16(image, ref curOffset);
            MinorVersion = NativeReader.ReadUInt16(image, ref curOffset);
            Flags        = NativeReader.ReadUInt32(image, ref curOffset);
            int nSections = NativeReader.ReadInt32(image, ref curOffset);

            Sections = new Dictionary <R2RSection.SectionType, R2RSection>();

            for (int i = 0; i < nSections; i++)
            {
                int type        = NativeReader.ReadInt32(image, ref curOffset);
                var sectionType = (R2RSection.SectionType)type;
                if (!Enum.IsDefined(typeof(R2RSection.SectionType), type))
                {
                    R2RDump.OutputWarning("Invalid ReadyToRun section type");
                }
                Sections[sectionType] = new R2RSection(sectionType,
                                                       NativeReader.ReadInt32(image, ref curOffset),
                                                       NativeReader.ReadInt32(image, ref curOffset));
            }

            Size = curOffset - startOffset;
        }
Example #5
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapimport.cpp">ZapImportSectionsTable::Save</a>
        /// </summary>
        private void ParseImportSections()
        {
            if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS))
            {
                return;
            }
            R2RSection importSectionsSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS];
            int        offset    = GetOffset(importSectionsSection.RelativeVirtualAddress);
            int        endOffset = offset + importSectionsSection.Size;

            while (offset < endOffset)
            {
                int rva                     = NativeReader.ReadInt32(Image, ref offset);
                int sectionOffset           = GetOffset(rva);
                int startOffset             = sectionOffset;
                int size                    = NativeReader.ReadInt32(Image, ref offset);
                CorCompileImportFlags flags = (CorCompileImportFlags)NativeReader.ReadUInt16(Image, ref offset);
                byte type                   = NativeReader.ReadByte(Image, ref offset);
                byte entrySize              = NativeReader.ReadByte(Image, ref offset);
                if (entrySize == 0)
                {
                    switch (Machine)
                    {
                    case Machine.I386:
                    case Machine.ArmThumb2:
                        entrySize = 4;
                        break;

                    case Machine.Amd64:
                    case Machine.IA64:
                    case Machine.Arm64:
                        entrySize = 8;
                        break;

                    default:
                        throw new NotImplementedException(Machine.ToString());
                    }
                }
                int entryCount = 0;
                if (entrySize != 0)
                {
                    entryCount = size / entrySize;
                }
                int signatureRVA = NativeReader.ReadInt32(Image, ref offset);

                int signatureOffset = 0;
                if (signatureRVA != 0)
                {
                    signatureOffset = GetOffset(signatureRVA);
                }
                List <R2RImportSection.ImportSectionEntry> entries = new List <R2RImportSection.ImportSectionEntry>();
                for (int i = 0; i < entryCount; i++)
                {
                    int    entryOffset = sectionOffset - startOffset;
                    long   section     = NativeReader.ReadInt64(Image, ref sectionOffset);
                    uint   sigRva      = NativeReader.ReadUInt32(Image, ref signatureOffset);
                    int    sigOffset   = GetOffset((int)sigRva);
                    string cellName    = MetadataNameFormatter.FormatSignature(this, sigOffset);
                    entries.Add(new R2RImportSection.ImportSectionEntry(entries.Count, entryOffset, section, sigRva, cellName));
                    ImportCellNames.Add(rva + entrySize * i, cellName);
                }

                int auxDataRVA    = NativeReader.ReadInt32(Image, ref offset);
                int auxDataOffset = 0;
                if (auxDataRVA != 0)
                {
                    auxDataOffset = GetOffset(auxDataRVA);
                }
                ImportSections.Add(new R2RImportSection(ImportSections.Count, Image, rva, size, flags, type, entrySize, signatureRVA, entries, auxDataRVA, auxDataOffset, Machine, R2RHeader.MajorVersion));
            }
        }
Example #6
0
        internal override void DumpSectionContents(R2RSection section, XmlNode parentNode = null)
        {
            switch (section.Type)
            {
            case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
                uint            availableTypesSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress);
                NativeParser    availableTypesParser        = new NativeParser(_r2r.Image, availableTypesSectionOffset);
                NativeHashtable availableTypes = new NativeHashtable(_r2r.Image, availableTypesParser, (uint)(availableTypesSectionOffset + section.Size));
                _writer.WriteLine(availableTypes.ToString());

                foreach (string name in _r2r.AvailableTypes)
                {
                    _writer.WriteLine(name);
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS:
                NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress));
                _writer.Write(methodEntryPoints.ToString());
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS:
                uint            instanceSectionOffset = (uint)_r2r.GetOffset(section.RelativeVirtualAddress);
                NativeParser    instanceParser        = new NativeParser(_r2r.Image, instanceSectionOffset);
                NativeHashtable instMethodEntryPoints = new NativeHashtable(_r2r.Image, instanceParser, (uint)(instanceSectionOffset + section.Size));
                _writer.Write(instMethodEntryPoints.ToString());
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS:
                int rtfOffset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int rtfEndOffset = rtfOffset + section.Size;
                int rtfIndex     = 0;
                while (rtfOffset < rtfEndOffset)
                {
                    uint rva = NativeReader.ReadUInt32(_r2r.Image, ref rtfOffset);
                    _writer.WriteLine($"{rtfIndex}: 0x{rva:X8}");
                    rtfIndex++;
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER:
                _writer.WriteLine(_r2r.CompilerIdentifier);
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
                foreach (R2RImportSection importSection in _r2r.ImportSections)
                {
                    _writer.Write(importSection.ToString());
                    if (_raw && importSection.Entries.Count != 0)
                    {
                        if (importSection.SectionRVA != 0)
                        {
                            _writer.WriteLine("Section Bytes:");
                            DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize);
                        }
                        if (importSection.SignatureRVA != 0)
                        {
                            _writer.WriteLine("Signature Bytes:");
                            DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int));
                        }
                        if (importSection.AuxiliaryDataRVA != 0)
                        {
                            _writer.WriteLine("AuxiliaryData Bytes:");
                            DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size);
                        }
                    }
                    foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
                    {
                        _writer.WriteLine(entry.ToString());
                    }
                    _writer.WriteLine();
                }
                break;
            }
        }
Example #7
0
        private void ParseImportSections()
        {
            if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS))
            {
                return;
            }
            R2RSection importSectionsSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS];
            int        offset    = GetOffset(importSectionsSection.RelativeVirtualAddress);
            int        endOffset = offset + importSectionsSection.Size;

            while (offset < endOffset)
            {
                int rva           = NativeReader.ReadInt32(Image, ref offset);
                int sectionOffset = GetOffset(rva);
                int startOffset   = sectionOffset;
                int size          = NativeReader.ReadInt32(Image, ref offset);
                R2RImportSection.CorCompileImportFlags flags = (R2RImportSection.CorCompileImportFlags)NativeReader.ReadUInt16(Image, ref offset);
                byte type       = NativeReader.ReadByte(Image, ref offset);
                byte entrySize  = NativeReader.ReadByte(Image, ref offset);
                int  entryCount = 0;
                if (entrySize != 0)
                {
                    entryCount = size / entrySize;
                }
                int signatureRVA = NativeReader.ReadInt32(Image, ref offset);

                int signatureOffset = 0;
                if (signatureRVA != 0)
                {
                    signatureOffset = GetOffset(signatureRVA);
                }
                List <R2RImportSection.ImportSectionEntry> entries = new List <R2RImportSection.ImportSectionEntry>();
                switch (flags)
                {
                case R2RImportSection.CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_EAGER:
                {
                    int  tempSignatureOffset = signatureOffset;
                    int  firstSigRva         = NativeReader.ReadInt32(Image, ref tempSignatureOffset);
                    uint sigRva = 0;
                    while (sigRva != firstSigRva)
                    {
                        int entryOffset = sectionOffset - startOffset;
                        sigRva = NativeReader.ReadUInt32(Image, ref signatureOffset);
                        long   section         = NativeReader.ReadInt64(Image, ref sectionOffset);
                        int    sigOff          = GetOffset((int)sigRva);
                        int    sigSampleLength = Math.Min(8, Image.Length - sigOff);
                        byte[] signatureSample = new byte[sigSampleLength];
                        Array.Copy(Image, sigOff, signatureSample, 0, sigSampleLength);
                        entries.Add(new R2RImportSection.ImportSectionEntry(entryOffset, section, sigRva, signatureSample));
                    }
                }
                break;

                case R2RImportSection.CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_CODE:
                case R2RImportSection.CorCompileImportFlags.CORCOMPILE_IMPORT_FLAGS_PCODE:
                    for (int i = 0; i < entryCount; i++)
                    {
                        int    entryOffset     = sectionOffset - startOffset;
                        long   section         = NativeReader.ReadInt64(Image, ref sectionOffset);
                        uint   sigRva          = NativeReader.ReadUInt32(Image, ref signatureOffset);
                        int    sigOff          = GetOffset((int)sigRva);
                        int    sigSampleLength = Math.Min(8, Image.Length - sigOff);
                        byte[] signatureSample = new byte[sigSampleLength];
                        Array.Copy(Image, sigOff, signatureSample, 0, sigSampleLength);
                        entries.Add(new R2RImportSection.ImportSectionEntry(entryOffset, section, sigRva, signatureSample));
                    }
                    break;
                }

                int auxDataRVA    = NativeReader.ReadInt32(Image, ref offset);
                int auxDataOffset = 0;
                if (auxDataRVA != 0)
                {
                    auxDataOffset = GetOffset(auxDataRVA);
                }
                ImportSections.Add(new R2RImportSection(Image, rva, size, flags, type, entrySize, signatureRVA, entries, auxDataRVA, auxDataOffset, Machine, R2RHeader.MajorVersion));
            }
        }
Example #8
0
        public bool TryGetAt(byte[] image, uint index, ref int pOffset)
        {
            if (index >= _nElements)
            {
                return(false);
            }

            uint offset = 0;

            if (_entryIndexSize == 0)
            {
                int i = (int)(_baseOffset + (index / _blockSize));
                offset = NativeReader.ReadByte(image, ref i);
            }
            else if (_entryIndexSize == 1)
            {
                int i = (int)(_baseOffset + 2 * (index / _blockSize));
                offset = NativeReader.ReadUInt16(image, ref i);
            }
            else
            {
                int i = (int)(_baseOffset + 4 * (index / _blockSize));
                offset = NativeReader.ReadUInt32(image, ref i);
            }
            offset += _baseOffset;

            for (uint bit = _blockSize >> 1; bit > 0; bit >>= 1)
            {
                uint val     = 0;
                uint offset2 = NativeReader.DecodeUnsigned(image, offset, ref val);
                if ((index & bit) != 0)
                {
                    if ((val & 2) != 0)
                    {
                        offset = offset + (val >> 2);
                        continue;
                    }
                }
                else
                {
                    if ((val & 1) != 0)
                    {
                        offset = offset2;
                        continue;
                    }
                }

                // Not found
                if ((val & 3) == 0)
                {
                    // Matching special leaf node?
                    if ((val >> 2) == (index & (_blockSize - 1)))
                    {
                        offset = offset2;
                        break;
                    }
                }
                return(false);
            }
            pOffset = (int)offset;
            return(true);
        }