Пример #1
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.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, entryOffset + rva, 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, this, rva, size, flags, type, entrySize, signatureRVA, entries, auxDataRVA, auxDataOffset, Machine, R2RHeader.MajorVersion));
            }
        }
Пример #2
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)
                {
                    int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    int endRva   = -1;
                    if (_r2r.Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    }
                    int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    _writer.WriteLine($"Index: {rtfIndex}");
                    _writer.WriteLine($"\tStartRva: 0x{startRva:X8}");
                    if (endRva != -1)
                    {
                        _writer.WriteLine($"\tEndRva: 0x{endRva:X8}");
                    }
                    _writer.WriteLine($"\tUnwindRva: 0x{unwindRva: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;
            }
        }
Пример #3
0
        internal override void DumpSectionContents(ReadyToRunSection section)
        {
            switch (section.Type)
            {
            case ReadyToRunSectionType.AvailableTypes:
                if (!_options.Naked)
                {
                    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());
                }

                if (_r2r.AvailableTypes.TryGetValue(section, out List <string> sectionTypes))
                {
                    _writer.WriteLine();
                    foreach (string name in sectionTypes)
                    {
                        _writer.WriteLine(name);
                    }
                }
                break;

            case ReadyToRunSectionType.MethodDefEntryPoints:
                if (!_options.Naked)
                {
                    NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress));
                    _writer.Write(methodEntryPoints.ToString());
                }

                if (_r2r.Methods.TryGetValue(section, out List <ReadyToRunMethod> sectionMethods))
                {
                    _writer.WriteLine();
                    foreach (ReadyToRunMethod method in sectionMethods)
                    {
                        _writer.WriteLine($@"{MetadataTokens.GetToken(method.MethodHandle):X8}: {method.SignatureString}");
                    }
                }
                break;

            case ReadyToRunSectionType.InstanceMethodEntryPoints:
                if (!_options.Naked)
                {
                    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());
                    _writer.WriteLine();
                }
                foreach (InstanceMethod instanceMethod in _r2r.InstanceMethods)
                {
                    _writer.WriteLine($@"0x{instanceMethod.Bucket:X2} -> {instanceMethod.Method.SignatureString}");
                }
                break;

            case ReadyToRunSectionType.RuntimeFunctions:
                int rtfOffset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int rtfEndOffset = rtfOffset + section.Size;
                int rtfIndex     = 0;
                while (rtfOffset < rtfEndOffset)
                {
                    int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    int endRva   = -1;
                    if (_r2r.Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    }
                    int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    _writer.WriteLine($"Index: {rtfIndex}");
                    _writer.WriteLine($"        StartRva: 0x{startRva:X8}");
                    if (endRva != -1)
                    {
                        _writer.WriteLine($"        EndRva: 0x{endRva:X8}");
                    }
                    _writer.WriteLine($"        UnwindRva: 0x{unwindRva:X8}");
                    rtfIndex++;
                }
                break;

            case ReadyToRunSectionType.CompilerIdentifier:
                _writer.WriteLine(_r2r.CompilerIdentifier);
                break;

            case ReadyToRunSectionType.ImportSections:
                if (_options.Naked)
                {
                    DumpNakedImportSections();
                }
                else
                {
                    foreach (ReadyToRunImportSection importSection in _r2r.ImportSections)
                    {
                        importSection.WriteTo(_writer);
                        if (_options.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 && importSection.AuxiliaryDataSize != 0)
                            {
                                _writer.WriteLine("AuxiliaryData Bytes:");
                                DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize);
                            }
                        }
                        foreach (ReadyToRunImportSection.ImportSectionEntry entry in importSection.Entries)
                        {
                            entry.WriteTo(_writer, _options);
                            _writer.WriteLine();
                        }
                        _writer.WriteLine();
                    }
                }
                break;

            case ReadyToRunSectionType.ManifestMetadata:
                int assemblyRefCount = 0;
                if (!_r2r.Composite)
                {
                    MetadataReader globalReader = _r2r.GetGlobalMetadataReader();
                    assemblyRefCount = globalReader.GetTableRowCount(TableIndex.AssemblyRef) + 1;
                    _writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):");
                    for (int assemblyRefIndex = 1; assemblyRefIndex < assemblyRefCount; assemblyRefIndex++)
                    {
                        AssemblyReference assemblyRef     = globalReader.GetAssemblyReference(MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex));
                        string            assemblyRefName = globalReader.GetString(assemblyRef.Name);
                        _writer.WriteLine($"[ID 0x{assemblyRefIndex:X2}]: {assemblyRefName}");
                    }
                }

                _writer.WriteLine($"Manifest metadata AssemblyRef's ({_r2r.ManifestReferenceAssemblies.Count} entries):");
                int manifestAsmIndex = 0;
                foreach (string manifestReferenceAssembly in _r2r.ManifestReferenceAssemblies.OrderBy(kvp => kvp.Value).Select(kvp => kvp.Key))
                {
                    _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 1:X2}]: {manifestReferenceAssembly}");
                    manifestAsmIndex++;
                }
                break;

            case ReadyToRunSectionType.AttributePresence:
                int attributesStartOffset     = _r2r.GetOffset(section.RelativeVirtualAddress);
                int attributesEndOffset       = attributesStartOffset + section.Size;
                NativeCuckooFilter attributes = new NativeCuckooFilter(_r2r.Image, attributesStartOffset, attributesEndOffset);
                _writer.WriteLine("Attribute presence filter");
                _writer.WriteLine(attributes.ToString());
                break;

            case ReadyToRunSectionType.InliningInfo:
                int iiOffset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int iiEndOffset = iiOffset + section.Size;
                InliningInfoSection inliningInfoSection = new InliningInfoSection(_r2r, iiOffset, iiEndOffset);
                _writer.WriteLine(inliningInfoSection.ToString());
                break;

            case ReadyToRunSectionType.InliningInfo2:
                int ii2Offset    = _r2r.GetOffset(section.RelativeVirtualAddress);
                int ii2EndOffset = ii2Offset + section.Size;
                InliningInfoSection2 inliningInfoSection2 = new InliningInfoSection2(_r2r, ii2Offset, ii2EndOffset);
                _writer.WriteLine(inliningInfoSection2.ToString());
                break;

            case ReadyToRunSectionType.OwnerCompositeExecutable:
                int oceOffset = _r2r.GetOffset(section.RelativeVirtualAddress);
                if (_r2r.Image[oceOffset + section.Size - 1] != 0)
                {
                    R2RDump.WriteWarning("String is not zero-terminated");
                }
                string ownerCompositeExecutable = Encoding.UTF8.GetString(_r2r.Image, oceOffset, section.Size - 1);     // exclude the zero terminator
                _writer.WriteLine("Composite executable: {0}", ownerCompositeExecutable.ToEscapedString());
                break;
            }
        }
Пример #4
0
        /// <summary>
        /// Get the RVAs of the runtime functions for each method
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindInfo::Save</a>
        /// </summary>
        private void ParseRuntimeFunctions(bool[] isEntryPoint, int runtimeFunctionOffset, int runtimeFunctionSize)
        {
            int curOffset = 0;

            foreach (R2RMethod method in R2RMethods)
            {
                int runtimeFunctionId = method.EntryPointRuntimeFunctionId;
                if (runtimeFunctionId == -1)
                {
                    continue;
                }
                curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize;
                BaseGcInfo gcInfo     = null;
                int        codeOffset = 0;
                do
                {
                    int startRva = NativeReader.ReadInt32(Image, ref curOffset);
                    int endRva   = -1;
                    if (Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(Image, ref curOffset);
                    }
                    int unwindRva    = NativeReader.ReadInt32(Image, ref curOffset);
                    int unwindOffset = GetOffset(unwindRva);

                    BaseUnwindInfo unwindInfo = null;
                    if (Machine == Machine.Amd64)
                    {
                        unwindInfo = new Amd64.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion);
                        }
                    }
                    else if (Machine == Machine.I386)
                    {
                        unwindInfo = new x86.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new x86.GcInfo(Image, unwindOffset, Machine, R2RHeader.MajorVersion);
                        }
                    }
                    else if (Machine == Machine.ArmThumb2)
                    {
                        unwindInfo = new Arm.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion); // Arm and Arm64 use the same GcInfo format as x64
                        }
                    }
                    else if (Machine == Machine.Arm64)
                    {
                        unwindInfo = new Arm64.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion);
                        }
                    }

                    EHInfo ehInfo = null;

                    EHInfoLocation ehInfoLocation;
                    if (EHLookupTable != null && EHLookupTable.RuntimeFunctionToEHInfoMap.TryGetValue(startRva, out ehInfoLocation))
                    {
                        ehInfo = new EHInfo(this, ehInfoLocation.EHInfoRVA, startRva, GetOffset(ehInfoLocation.EHInfoRVA), ehInfoLocation.ClauseCount);
                    }

                    RuntimeFunction rtf = new RuntimeFunction(
                        runtimeFunctionId,
                        startRva,
                        endRva,
                        unwindRva,
                        codeOffset,
                        method,
                        unwindInfo,
                        gcInfo,
                        ehInfo,
                        _runtimeFunctionToDebugInfo.GetValueOrDefault(runtimeFunctionId));

                    method.RuntimeFunctions.Add(rtf);
                    runtimeFunctionId++;
                    codeOffset += rtf.Size;
                }while (runtimeFunctionId < isEntryPoint.Length && !isEntryPoint[runtimeFunctionId]);
            }
        }
Пример #5
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));
            }
        }
Пример #6
0
        internal override void DumpSectionContents(R2RSection section, XmlNode parentNode = null)
        {
            switch (section.Type)
            {
            case R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES:
                if (!_options.Naked)
                {
                    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:
                if (!_options.Naked)
                {
                    NativeArray methodEntryPoints = new NativeArray(_r2r.Image, (uint)_r2r.GetOffset(section.RelativeVirtualAddress));
                    _writer.Write(methodEntryPoints.ToString());
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS:
                if (!_options.Naked)
                {
                    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());
                    _writer.WriteLine();
                }
                foreach (InstanceMethod instanceMethod in _r2r.InstanceMethods)
                {
                    _writer.WriteLine($@"0x{instanceMethod.Bucket:X2} -> {instanceMethod.Method.SignatureString}");
                }
                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)
                {
                    int startRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    int endRva   = -1;
                    if (_r2r.Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    }
                    int unwindRva = NativeReader.ReadInt32(_r2r.Image, ref rtfOffset);
                    _writer.WriteLine($"Index: {rtfIndex}");
                    _writer.WriteLine($"\tStartRva: 0x{startRva:X8}");
                    if (endRva != -1)
                    {
                        _writer.WriteLine($"\tEndRva: 0x{endRva:X8}");
                    }
                    _writer.WriteLine($"\tUnwindRva: 0x{unwindRva:X8}");
                    rtfIndex++;
                }
                break;

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

            case R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS:
                if (_options.Naked)
                {
                    DumpNakedImportSections();
                }
                else
                {
                    foreach (R2RImportSection importSection in _r2r.ImportSections)
                    {
                        importSection.WriteTo(_writer);
                        if (_options.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 && importSection.AuxiliaryDataSize != 0)
                            {
                                _writer.WriteLine("AuxiliaryData Bytes:");
                                DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize);
                            }
                        }
                        foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
                        {
                            entry.WriteTo(_writer, _options);
                            _writer.WriteLine();
                        }
                        _writer.WriteLine();
                    }
                }
                break;

            case R2RSection.SectionType.READYTORUN_SECTION_MANIFEST_METADATA:
                int assemblyRefCount = _r2r.MetadataReader.GetTableRowCount(TableIndex.AssemblyRef);
                _writer.WriteLine($"MSIL AssemblyRef's ({assemblyRefCount} entries):");
                for (int assemblyRefIndex = 1; assemblyRefIndex <= assemblyRefCount; assemblyRefIndex++)
                {
                    AssemblyReference assemblyRef     = _r2r.MetadataReader.GetAssemblyReference(MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex));
                    string            assemblyRefName = _r2r.MetadataReader.GetString(assemblyRef.Name);
                    _writer.WriteLine($"[ID 0x{assemblyRefIndex:X2}]: {assemblyRefName}");
                }

                _writer.WriteLine($"Manifest metadata AssemblyRef's ({_r2r.ManifestReferenceAssemblies.Count} entries):");
                for (int manifestAsmIndex = 0; manifestAsmIndex < _r2r.ManifestReferenceAssemblies.Count; manifestAsmIndex++)
                {
                    _writer.WriteLine($"[ID 0x{manifestAsmIndex + assemblyRefCount + 2:X2}]: {_r2r.ManifestReferenceAssemblies[manifestAsmIndex]}");
                }
                break;
            }
        }
Пример #7
0
        public Dictionary <int, GcTransition> GetTranstions(byte[] image, ref int bitOffset)
        {
            int totalInterruptibleLength = 0;

            if (NumInterruptibleRanges == 0)
            {
                totalInterruptibleLength = CodeLength;
            }
            else
            {
                foreach (InterruptibleRange range in InterruptibleRanges)
                {
                    totalInterruptibleLength += (int)(range.StopOffset - range.StartOffset);
                }
            }

            int numChunks         = (totalInterruptibleLength + _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK - 1) / _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK; //=2
            int numBitsPerPointer = (int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.POINTER_SIZE_ENCBASE, ref bitOffset);

            if (numBitsPerPointer == 0)
            {
                return(new Dictionary <int, GcTransition>());
            }

            int[] chunkPointers = new int[numChunks];
            for (int i = 0; i < numChunks; i++)
            {
                chunkPointers[i] = NativeReader.ReadBits(image, numBitsPerPointer, ref bitOffset);
            }
            int info2Offset = (int)Math.Ceiling(bitOffset / 8.0) * 8;

            List <GcTransition> transitions = new List <GcTransition>();

            bool[] liveAtEnd = new bool[SlotTable.GcSlots.Count - SlotTable.NumUntracked];
            for (int currentChunk = 0; currentChunk < numChunks; currentChunk++)
            {
                if (chunkPointers[currentChunk] == 0)
                {
                    continue;
                }
                else
                {
                    bitOffset = info2Offset + chunkPointers[currentChunk] - 1;
                }

                int  couldBeLiveOffset = bitOffset;
                int  slotId            = 0;
                bool fSimple           = (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0);
                bool fSkipFirst        = false;
                int  couldBeLiveCnt    = 0;
                if (!fSimple)
                {
                    fSkipFirst = (NativeReader.ReadBits(image, 1, ref couldBeLiveOffset) == 0);
                    slotId     = -1;
                }

                uint numCouldBeLiveSlots = GetNumCouldBeLiveSlots(image, ref bitOffset);

                int finalStateOffset = bitOffset;
                bitOffset += (int)numCouldBeLiveSlots;

                int normChunkBaseCodeOffset = currentChunk * _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK;
                for (int i = 0; i < numCouldBeLiveSlots; i++)
                {
                    slotId = GetNextSlotId(image, fSimple, fSkipFirst, slotId, ref couldBeLiveCnt, ref couldBeLiveOffset);

                    bool isLive = !liveAtEnd[slotId];
                    liveAtEnd[slotId] = (NativeReader.ReadBits(image, 1, ref finalStateOffset) != 0);

                    // Read transitions
                    while (NativeReader.ReadBits(image, 1, ref bitOffset) != 0)
                    {
                        int transitionOffset = NativeReader.ReadBits(image, _gcInfoTypes.NUM_NORM_CODE_OFFSETS_PER_CHUNK_LOG2, ref bitOffset) + normChunkBaseCodeOffset;
                        transitions.Add(new GcTransition(transitionOffset, slotId, isLive, currentChunk));
                        isLive = !isLive;
                    }
                    slotId++;
                }
            }

            transitions.Sort((s1, s2) => s1.CodeOffset.CompareTo(s2.CodeOffset));

            return(UpdateTransitionCodeOffset(transitions));
        }
Пример #8
0
        /// <summary>
        /// Initializes the fields of the R2RHeader and R2RMethods
        /// </summary>
        /// <param name="filename">PE image</param>
        /// <exception cref="BadImageFormatException">The Cor header flag must be ILLibrary</exception>
        public unsafe R2RReader(string filename)
        {
            Filename = filename;
            Image    = File.ReadAllBytes(filename);

            fixed(byte *p = Image)
            {
                IntPtr ptr = (IntPtr)p;

                peReader = new PEReader(p, Image.Length);

                IsR2R = (peReader.PEHeaders.CorHeader.Flags == CorFlags.ILLibrary);
                if (!IsR2R)
                {
                    throw new BadImageFormatException("The file is not a ReadyToRun image");
                }

                Machine   = peReader.PEHeaders.CoffHeader.Machine;
                ImageBase = peReader.PEHeaders.PEHeader.ImageBase;

                // initialize R2RHeader
                DirectoryEntry r2rHeaderDirectory = peReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory;
                int            r2rHeaderOffset    = GetOffset(r2rHeaderDirectory.RelativeVirtualAddress);

                R2RHeader = new R2RHeader(Image, r2rHeaderDirectory.RelativeVirtualAddress, r2rHeaderOffset);
                if (r2rHeaderDirectory.Size != R2RHeader.Size)
                {
                    throw new BadImageFormatException("The calculated size of the R2RHeader doesn't match the size saved in the ManagedNativeHeaderDirectory");
                }

                // initialize R2RMethods
                if (peReader.HasMetadata)
                {
                    MetadataReader mdReader = peReader.GetMetadataReader();

                    int runtimeFunctionSize = 2;
                    if (Machine == Machine.Amd64)
                    {
                        runtimeFunctionSize = 3;
                    }
                    runtimeFunctionSize *= sizeof(int);
                    R2RSection runtimeFunctionSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS];
                    uint       nRuntimeFunctions      = (uint)(runtimeFunctionSection.Size / runtimeFunctionSize);
                    int        runtimeFunctionOffset  = GetOffset(runtimeFunctionSection.RelativeVirtualAddress);
                    bool[]     isEntryPoint           = new bool[nRuntimeFunctions];
                    for (int i = 0; i < nRuntimeFunctions; i++)
                    {
                        isEntryPoint[i] = false;
                    }

                    // initialize R2RMethods with method signatures from MethodDefHandle, and runtime function indices from MethodDefEntryPoints
                    int         methodDefEntryPointsRVA    = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS].RelativeVirtualAddress;
                    int         methodDefEntryPointsOffset = GetOffset(methodDefEntryPointsRVA);
                    NativeArray methodEntryPoints          = new NativeArray(Image, (uint)methodDefEntryPointsOffset);
                    uint        nMethodEntryPoints         = methodEntryPoints.GetCount();
                    R2RMethods = new List <R2RMethod>();
                    for (uint rid = 1; rid <= nMethodEntryPoints; rid++)
                    {
                        int offset = 0;
                        if (methodEntryPoints.TryGetAt(Image, rid - 1, ref offset))
                        {
                            R2RMethod method = new R2RMethod(Image, mdReader, rid, GetEntryPointIdFromOffset(offset), null, null);

                            if (method.EntryPointRuntimeFunctionId < 0 || method.EntryPointRuntimeFunctionId >= nRuntimeFunctions)
                            {
                                throw new BadImageFormatException("EntryPointRuntimeFunctionId out of bounds");
                            }
                            isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                            R2RMethods.Add(method);
                        }
                    }

                    // instance method table
                    R2RSection      instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS];
                    int             instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress);
                    NativeParser    parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset);
                    NativeHashtable instMethodEntryPoints = new NativeHashtable(Image, parser);
                    NativeHashtable.AllEntriesEnumerator allEntriesEnum = instMethodEntryPoints.EnumerateAllEntries();
                    NativeParser curParser = allEntriesEnum.GetNext();
                    while (!curParser.IsNull())
                    {
                        uint methodFlags = curParser.GetCompressedData();
                        uint rid         = curParser.GetCompressedData();
                        if ((methodFlags & (byte)R2RMethod.EncodeMethodSigFlags.ENCODE_METHOD_SIG_MethodInstantiation) != 0)
                        {
                            uint nArgs = curParser.GetCompressedData();
                            R2RMethod.GenericElementTypes[] args = new R2RMethod.GenericElementTypes[nArgs];
                            uint[] tokens = new uint[nArgs];
                            for (int i = 0; i < nArgs; i++)
                            {
                                args[i] = (R2RMethod.GenericElementTypes)curParser.GetByte();
                                if (args[i] == R2RMethod.GenericElementTypes.ValueType)
                                {
                                    tokens[i] = curParser.GetCompressedData();
                                    tokens[i] = (tokens[i] >> 2);
                                }
                            }

                            uint id = curParser.GetUnsigned();
                            id = id >> 1;
                            R2RMethod method = new R2RMethod(Image, mdReader, rid, (int)id, args, tokens);
                            if (method.EntryPointRuntimeFunctionId >= 0 && method.EntryPointRuntimeFunctionId < nRuntimeFunctions)
                            {
                                isEntryPoint[method.EntryPointRuntimeFunctionId] = true;
                            }
                            R2RMethods.Add(method);
                        }
                        curParser = allEntriesEnum.GetNext();
                    }

                    // get the RVAs of the runtime functions for each method
                    int curOffset = 0;
                    foreach (R2RMethod method in R2RMethods)
                    {
                        int runtimeFunctionId = method.EntryPointRuntimeFunctionId;
                        if (runtimeFunctionId == -1)
                        {
                            continue;
                        }
                        curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize;
                        do
                        {
                            int startRva = NativeReader.ReadInt32(Image, ref curOffset);
                            int endRva   = -1;
                            if (Machine == Machine.Amd64)
                            {
                                endRva = NativeReader.ReadInt32(Image, ref curOffset);
                            }
                            int unwindRva = NativeReader.ReadInt32(Image, ref curOffset);

                            method.RuntimeFunctions.Add(new RuntimeFunction(runtimeFunctionId, startRva, endRva, unwindRva, method));
                            runtimeFunctionId++;
                        }while (runtimeFunctionId < nRuntimeFunctions && !isEntryPoint[runtimeFunctionId]);
                    }
                }
            }
        }
Пример #9
0
        public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion)
        {
            Offset       = offset;
            _gcInfoTypes = new GcInfoTypes(machine);

            SecurityObjectStackSlot            = -1;
            GSCookieStackSlot                  = -1;
            PSPSymStackSlot                    = -1;
            SecurityObjectStackSlot            = -1;
            GenericsInstContextStackSlot       = -1;
            StackBaseRegister                  = 0xffffffff;
            SizeOfEditAndContinuePreservedArea = 0xffffffff;
            ReversePInvokeFrameStackSlot       = -1;

            Version = ReadyToRunVersionToGcInfoVersion(majorVersion);
            int bitOffset      = offset * 8;
            int startBitOffset = bitOffset;

            ParseHeaderFlags(image, ref bitOffset);

            if (Version >= MIN_GCINFO_VERSION_WITH_RETURN_KIND) // IsReturnKindAvailable
            {
                int returnKindBits = (_slimHeader) ? _gcInfoTypes.SIZE_OF_RETURN_KIND_SLIM : _gcInfoTypes.SIZE_OF_RETURN_KIND_FAT;
                ReturnKind = (ReturnKinds)NativeReader.ReadBits(image, returnKindBits, ref bitOffset);
            }

            CodeLength = _gcInfoTypes.DenormalizeCodeLength((int)NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.CODE_LENGTH_ENCBASE, ref bitOffset));

            if (_hasGSCookie)
            {
                uint normPrologSize = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1;
                uint normEpilogSize = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset);

                ValidRangeStart = normPrologSize;
                ValidRangeEnd   = (uint)CodeLength - normEpilogSize;
            }
            else if (_hasSecurityObject || _hasGenericsInstContext)
            {
                ValidRangeStart = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NORM_PROLOG_SIZE_ENCBASE, ref bitOffset) + 1;
                ValidRangeEnd   = ValidRangeStart + 1;
            }

            if (_hasSecurityObject)
            {
                SecurityObjectStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.SECURITY_OBJECT_STACK_SLOT_ENCBASE, ref bitOffset));
            }

            if (_hasGSCookie)
            {
                GSCookieStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.GS_COOKIE_STACK_SLOT_ENCBASE, ref bitOffset));
            }

            if (_hasPSPSym)
            {
                PSPSymStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.PSP_SYM_STACK_SLOT_ENCBASE, ref bitOffset));
            }

            if (_hasGenericsInstContext)
            {
                GenericsInstContextStackSlot = _gcInfoTypes.DenormalizeStackSlot(NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE, ref bitOffset));
            }

            if (_hasStackBaseRegister && !_slimHeader)
            {
                StackBaseRegister = _gcInfoTypes.DenormalizeStackBaseRegister(NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.STACK_BASE_REGISTER_ENCBASE, ref bitOffset));
            }

            if (_hasSizeOfEditAndContinuePreservedArea)
            {
                SizeOfEditAndContinuePreservedArea = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE, ref bitOffset);
            }

            if (_hasReversePInvokeFrame)
            {
                ReversePInvokeFrameStackSlot = NativeReader.DecodeVarLengthSigned(image, _gcInfoTypes.REVERSE_PINVOKE_FRAME_ENCBASE, ref bitOffset);
            }

            // FIXED_STACK_PARAMETER_SCRATCH_AREA (this macro is always defined in _gcInfoTypes.h)
            if (!_slimHeader)
            {
                SizeOfStackOutgoingAndScratchArea = _gcInfoTypes.DenormalizeSizeOfStackArea(NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.SIZE_OF_STACK_AREA_ENCBASE, ref bitOffset));
            }

            // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED (this macro is always defined in _gcInfoTypes.h)
            NumSafePoints = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NUM_SAFE_POINTS_ENCBASE, ref bitOffset);

            if (!_slimHeader)
            {
                NumInterruptibleRanges = NativeReader.DecodeVarLengthUnsigned(image, _gcInfoTypes.NUM_INTERRUPTIBLE_RANGES_ENCBASE, ref bitOffset);
            }

            // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED (this macro is always defined in _gcInfoTypes.h)
            SafePointOffsets = EnumerateSafePoints(image, ref bitOffset);
            uint numBitsPerOffset = GcInfoTypes.CeilOfLog2(CodeLength);

            bitOffset += (int)(NumSafePoints * numBitsPerOffset);

            InterruptibleRanges = EnumerateInterruptibleRanges(image, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, _gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset);

            SlotTable = new GcSlotTable(image, machine, _gcInfoTypes, ref bitOffset);

            Transitions = GetTranstions(image, ref bitOffset);

            Size = bitOffset - startBitOffset;

            _machine = machine;
        }
Пример #10
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:
                if (_ignoreSensitive)
                {
                    break;
                }
                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)
                {
                    XmlNode importSectionsNode = XmlDocument.CreateNode("element", "ImportSection", "");
                    AddXMLAttribute(importSectionsNode, "Index", $"{importSection.Index}");
                    contentsNode.AppendChild(importSectionsNode);

                    Serialize(importSection, importSectionsNode);
                    if (_options.Raw && importSection.Entries.Count != 0)
                    {
                        if (importSection.SectionRVA != 0)
                        {
                            DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize, importSectionsNode, "SectionBytes");
                        }
                        if (importSection.SignatureRVA != 0)
                        {
                            DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int), importSectionsNode, "SignatureBytes");
                        }
                        if (importSection.AuxiliaryDataRVA != 0)
                        {
                            DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryDataSize, importSectionsNode, "AuxiliaryDataBytes");
                        }
                    }
                    foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
                    {
                        Serialize(entry, importSectionsNode);
                    }
                }
                break;
            }
        }
Пример #11
0
        /// <summary>
        /// Get the RVAs of the runtime functions for each method
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindInfo::Save</a>
        /// </summary>
        private void ParseRuntimeFunctions(bool[] isEntryPoint, int runtimeFunctionOffset, int runtimeFunctionSize)
        {
            int curOffset = 0;

            foreach (R2RMethod method in R2RMethods)
            {
                int runtimeFunctionId = method.EntryPointRuntimeFunctionId;
                if (runtimeFunctionId == -1)
                {
                    continue;
                }
                curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize;
                BaseGcInfo gcInfo     = null;
                int        codeOffset = 0;
                do
                {
                    int startRva = NativeReader.ReadInt32(Image, ref curOffset);
                    int endRva   = -1;
                    if (Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(Image, ref curOffset);
                    }
                    int unwindRva    = NativeReader.ReadInt32(Image, ref curOffset);
                    int unwindOffset = GetOffset(unwindRva);

                    BaseUnwindInfo unwindInfo = null;
                    if (Machine == Machine.Amd64)
                    {
                        unwindInfo = new Amd64.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion);
                        }
                    }
                    else if (Machine == Machine.I386)
                    {
                        unwindInfo = new x86.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new x86.GcInfo(Image, unwindOffset, Machine, R2RHeader.MajorVersion);
                        }
                    }
                    else if (Machine == Machine.ArmThumb2)
                    {
                        unwindInfo = new Arm.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion); // Arm and Arm64 use the same GcInfo format as x64
                        }
                    }
                    else if (Machine == Machine.Arm64)
                    {
                        unwindInfo = new Arm64.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion);
                        }
                    }

                    RuntimeFunction rtf = new RuntimeFunction(runtimeFunctionId, startRva, endRva, unwindRva, codeOffset, method, unwindInfo, gcInfo);
                    method.RuntimeFunctions.Add(rtf);
                    runtimeFunctionId++;
                    codeOffset += rtf.Size;
                }while (runtimeFunctionId < isEntryPoint.Length && !isEntryPoint[runtimeFunctionId]);
            }
        }
Пример #12
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);
        }
Пример #13
0
        private void DumpSectionContents(R2RReader r2r, R2RSection section)
        {
            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.CompileIdentifier);
                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(r2r, importSection.SectionRVA, (uint)importSection.SectionSize);
                        }
                        if (importSection.SignatureRVA != 0)
                        {
                            _writer.WriteLine("Signature Bytes:");
                            DumpBytes(r2r, importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int));
                        }
                        if (importSection.AuxiliaryDataRVA != 0)
                        {
                            _writer.WriteLine("AuxiliaryData Bytes:");
                            DumpBytes(r2r, importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size);
                        }
                    }
                    foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries)
                    {
                        _writer.WriteLine();
                        _writer.WriteLine(entry.ToString());
                    }
                    _writer.WriteLine();
                }
                break;
            }
        }