Пример #1
0
        public XmlDumper(bool ignoreSensitive, R2RReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options)
            : base(r2r, writer, disassembler, options)
        {
            _ignoreSensitive = ignoreSensitive;
            XmlDocument      = new XmlDocument();

            _ignoredProperties = new XmlAttributeOverrides();
            XmlAttributes attrs = new XmlAttributes();

            attrs.XmlIgnore = _ignoreSensitive;
            _ignoredProperties.Add(typeof(R2RHeader), "RelativeVirtualAddress", attrs);
            _ignoredProperties.Add(typeof(R2RHeader), "Size", attrs);
            _ignoredProperties.Add(typeof(R2RImportSection), "SectionRVA", attrs);
            _ignoredProperties.Add(typeof(R2RImportSection), "SectionSize", attrs);
            _ignoredProperties.Add(typeof(R2RImportSection), "EntrySize", attrs);
            _ignoredProperties.Add(typeof(R2RImportSection), "SignatureRVA", attrs);
            _ignoredProperties.Add(typeof(R2RImportSection), "AuxiliaryDataRVA", attrs);
            _ignoredProperties.Add(typeof(R2RImportSection.ImportSectionEntry), "SignatureSample", attrs);
            _ignoredProperties.Add(typeof(R2RImportSection.ImportSectionEntry), "SignatureRVA", attrs);
            _ignoredProperties.Add(typeof(RuntimeFunction), "StartAddress", attrs);
            _ignoredProperties.Add(typeof(RuntimeFunction), "UnwindRVA", attrs);
            _ignoredProperties.Add(typeof(R2RSection), "RelativeVirtualAddress", attrs);
            _ignoredProperties.Add(typeof(R2RSection), "Size", attrs);
        }
Пример #2
0
 public Dumper(ReadyToRunReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options)
 {
     _r2r          = r2r;
     _writer       = writer;
     _disassembler = disassembler;
     _options      = options;
 }
Пример #3
0
 public TextDumper(ReadyToRunReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options)
     : base(r2r, writer, disassembler, options)
 {
 }
Пример #4
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(DumpOptions options, string filename)
            : base(options, filename, new List <string>())
        {
            IsR2R = ((PEReader.PEHeaders.CorHeader.Flags & CorFlags.ILLibrary) != 0);
            if (!IsR2R)
            {
                throw new BadImageFormatException("The file is not a ReadyToRun image");
            }

            uint machine = (uint)PEReader.PEHeaders.CoffHeader.Machine;

            OS = OperatingSystem.Unknown;
            foreach (OperatingSystem os in Enum.GetValues(typeof(OperatingSystem)))
            {
                Machine = (Machine)(machine ^ (uint)os);
                if (Enum.IsDefined(typeof(Machine), Machine))
                {
                    OS = os;
                    break;
                }
            }
            if (OS == OperatingSystem.Unknown)
            {
                throw new BadImageFormatException($"Invalid Machine: {machine}");
            }

            switch (Machine)
            {
            case Machine.I386:
                Architecture = Architecture.X86;
                PointerSize  = 4;
                break;

            case Machine.Amd64:
                Architecture = Architecture.X64;
                PointerSize  = 8;
                break;

            case Machine.Arm:
            case Machine.Thumb:
            case Machine.ArmThumb2:
                Architecture = Architecture.Arm;
                PointerSize  = 4;
                break;

            case Machine.Arm64:
                Architecture = Architecture.Arm64;
                PointerSize  = 8;
                break;

            default:
                throw new NotImplementedException(Machine.ToString());
            }


            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");
            }

            ParseDebugInfo();

            if (R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_MANIFEST_METADATA))
            {
                R2RSection manifestMetadata = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_MANIFEST_METADATA];
                fixed(byte *image = Image)
                {
                    MetadataReader manifestReader   = new MetadataReader(image + GetOffset(manifestMetadata.RelativeVirtualAddress), manifestMetadata.Size);
                    int            assemblyRefCount = manifestReader.GetTableRowCount(TableIndex.AssemblyRef);

                    for (int assemblyRefIndex = 1; assemblyRefIndex <= assemblyRefCount; assemblyRefIndex++)
                    {
                        AssemblyReferenceHandle asmRefHandle = MetadataTokens.AssemblyReferenceHandle(assemblyRefIndex);
                        AssemblyReference       asmRef       = manifestReader.GetAssemblyReference(asmRefHandle);
                        string asmRefName = manifestReader.GetString(asmRef.Name);
                        ManifestReferenceAssemblies.Add(asmRefName);
                    }
                }
            }

            if (R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_EXCEPTION_INFO))
            {
                R2RSection exceptionInfoSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_EXCEPTION_INFO];
                EHLookupTable = new EHLookupTable(Image, GetOffset(exceptionInfoSection.RelativeVirtualAddress), exceptionInfoSection.Size);
            }

            ImportSections  = new List <R2RImportSection>();
            ImportCellNames = new Dictionary <int, string>();
            ParseImportSections();

            R2RMethods      = new List <R2RMethod>();
            InstanceMethods = new List <InstanceMethod>();

            if (R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS))
            {
                int        runtimeFunctionSize    = CalculateRuntimeFunctionSize();
                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];

                // initialize R2RMethods
                ParseMethodDefEntrypoints(isEntryPoint);
                ParseInstanceMethodEntrypoints(isEntryPoint);
                ParseRuntimeFunctions(isEntryPoint, runtimeFunctionOffset, runtimeFunctionSize);
            }

            AvailableTypes = new List <string>();
            ParseAvailableTypes();

            CompilerIdentifier = ParseCompilerIdentifier();
        }
Пример #5
0
        public void WriteTo(TextWriter writer, DumpOptions options)
        {
            if (!options.Naked)
            {
                writer.WriteLine($"Id: {Id}");
                writer.WriteLine($"StartAddress: 0x{StartAddress:X8}");
            }
            if (Size == -1)
            {
                writer.WriteLine("Size: Unavailable");
            }
            else
            {
                writer.WriteLine($"Size: {Size} bytes");
            }
            if (!options.Naked)
            {
                writer.WriteLine($"UnwindRVA: 0x{UnwindRVA:X8}");
            }
            if (UnwindInfo is Amd64.UnwindInfo amd64UnwindInfo)
            {
                string parsedFlags = "";
                if ((amd64UnwindInfo.Flags & (int)Amd64.UnwindFlags.UNW_FLAG_EHANDLER) != 0)
                {
                    parsedFlags += " EHANDLER";
                }
                if ((amd64UnwindInfo.Flags & (int)Amd64.UnwindFlags.UNW_FLAG_UHANDLER) != 0)
                {
                    parsedFlags += " UHANDLER";
                }
                if ((amd64UnwindInfo.Flags & (int)Amd64.UnwindFlags.UNW_FLAG_CHAININFO) != 0)
                {
                    parsedFlags += " CHAININFO";
                }
                if (parsedFlags.Length == 0)
                {
                    parsedFlags = " NHANDLER";
                }
                writer.WriteLine($"Version:            {amd64UnwindInfo.Version}");
                writer.WriteLine($"Flags:              0x{amd64UnwindInfo.Flags:X2}{parsedFlags}");
                writer.WriteLine($"SizeOfProlog:       0x{amd64UnwindInfo.SizeOfProlog:X4}");
                writer.WriteLine($"CountOfUnwindCodes: {amd64UnwindInfo.CountOfUnwindCodes}");
                writer.WriteLine($"FrameRegister:      {amd64UnwindInfo.FrameRegister}");
                writer.WriteLine($"FrameOffset:        0x{amd64UnwindInfo.FrameOffset}");
                if (!options.Naked)
                {
                    writer.WriteLine($"PersonalityRVA:     0x{amd64UnwindInfo.PersonalityRoutineRVA:X4}");
                }

                for (int unwindCodeIndex = 0; unwindCodeIndex < amd64UnwindInfo.CountOfUnwindCodes; unwindCodeIndex++)
                {
                    Amd64.UnwindCode unwindCode = amd64UnwindInfo.UnwindCodeArray[unwindCodeIndex];
                    writer.Write($"UnwindCode[{unwindCode.Index}]: ");
                    writer.Write($"CodeOffset 0x{unwindCode.CodeOffset:X4} ");
                    writer.Write($"FrameOffset 0x{unwindCode.FrameOffset:X4} ");
                    writer.Write($"NextOffset 0x{unwindCode.NextFrameOffset} ");
                    writer.Write($"Op {unwindCode.OpInfoStr}");
                    writer.WriteLine();
                }
            }
            writer.WriteLine();

            if (Method.GcInfo is Amd64.GcInfo gcInfo)
            {
                writer.WriteLine("GC info:");
                writer.WriteLine($@"    Version:                           {gcInfo.Version}");
                writer.WriteLine($@"    ReturnKind:                        {gcInfo.ReturnKind}");
                writer.WriteLine($@"    ValidRangeStart:                   0x{gcInfo.ValidRangeStart:X4}");
                writer.WriteLine($@"    ValidRangeEnd:                     0x{gcInfo.ValidRangeEnd:X4}");
                writer.WriteLine($@"    SecurityObjectStackSlot:           0x{gcInfo.SecurityObjectStackSlot:X4}");
                writer.WriteLine($@"    GSCookieStackSlot:                 0x{gcInfo.GSCookieStackSlot:X4}");
                writer.WriteLine($@"    PSPSymStackSlot:                   0x{gcInfo.PSPSymStackSlot:X4}");
                writer.WriteLine($@"    GenericsInstContextStackSlot:      0x{gcInfo.GenericsInstContextStackSlot:X4}");
                writer.WriteLine($@"    StackBaseRegister:                 {gcInfo.StackBaseRegister}");
                writer.WriteLine($@"    SizeOfENCPreservedArea:            0x{gcInfo.SizeOfEditAndContinuePreservedArea:X4}");
                writer.WriteLine($@"    ReversePInvokeFrameStackSlot:      0x{gcInfo.ReversePInvokeFrameStackSlot:X4}");
                writer.WriteLine($@"    SizeOfStackOutgoingAndScratchArea: 0x{gcInfo.SizeOfStackOutgoingAndScratchArea:X4}");
                writer.WriteLine($@"    NumSafePoints:                     {gcInfo.NumSafePoints}");
                writer.WriteLine($@"    NumInterruptibleRanges:            {gcInfo.NumInterruptibleRanges}");

                writer.WriteLine($@"    SafePointOffsets: {gcInfo.SafePointOffsets.Count}");
                foreach (Amd64.GcInfo.SafePointOffset safePoint in gcInfo.SafePointOffsets)
                {
                    writer.WriteLine($@"        Index: {safePoint.Index,2}; Value: 0x{safePoint.Value:X4}");
                }

                writer.WriteLine($@"    InterruptibleRanges: {gcInfo.InterruptibleRanges.Count}");
                foreach (Amd64.InterruptibleRange range in gcInfo.InterruptibleRanges)
                {
                    writer.WriteLine($@"        Index: {range.Index,2}; StartOffset: 0x{range.StartOffset:X4}; StopOffset: 0x{range.StopOffset:X4}");
                }

                writer.WriteLine("    SlotTable:");
                writer.WriteLine($@"        NumRegisters:  {gcInfo.SlotTable.NumRegisters}");
                writer.WriteLine($@"        NumStackSlots: {gcInfo.SlotTable.NumStackSlots}");
                writer.WriteLine($@"        NumUntracked:  {gcInfo.SlotTable.NumUntracked}");
                writer.WriteLine($@"        NumSlots:      {gcInfo.SlotTable.NumSlots}");
                writer.WriteLine($@"        GcSlots:       {gcInfo.SlotTable.GcSlots.Count}");
                foreach (Amd64.GcSlotTable.GcSlot slot in gcInfo.SlotTable.GcSlots)
                {
                    writer.WriteLine($@"            Index: {slot.Index,2}; RegisterNumber: {slot.RegisterNumber,2}; Flags: {slot.Flags}");
                }
                writer.WriteLine();
            }

            if (EHInfo != null)
            {
                writer.WriteLine($@"EH info @ {EHInfo.EHInfoRVA:X4}, #clauses = {EHInfo.EHClauses.Length}");
                EHInfo.WriteTo(writer);
                writer.WriteLine();
            }

            if (DebugInfo != null)
            {
                DebugInfo.WriteTo(writer, options);
            }
        }
Пример #6
0
        public void WriteTo(TextWriter writer, DumpOptions dumpOptions)
        {
            if (_boundsList.Count > 0)
            {
                writer.WriteLine("Debug Info");
            }

            writer.WriteLine("\tBounds:");
            for (int i = 0; i < _boundsList.Count; ++i)
            {
                writer.Write('\t');
                if (!dumpOptions.Naked)
                {
                    writer.Write($"Native Offset: 0x{_boundsList[i].NativeOffset:X}, ");
                }
                writer.WriteLine($"IL Offset: 0x{_boundsList[i].ILOffset:X}, Source Types: {_boundsList[i].SourceTypes}");
            }

            writer.WriteLine("");

            if (_variablesList.Count > 0)
            {
                writer.WriteLine("\tVariable Locations:");
            }

            for (int i = 0; i < _variablesList.Count; ++i)
            {
                var varLoc = _variablesList[i];
                writer.WriteLine($"\tVariable Number: {varLoc.VariableNumber}");
                writer.WriteLine($"\tStart Offset: 0x{varLoc.StartOffset:X}");
                writer.WriteLine($"\tEnd Offset: 0x{varLoc.EndOffset:X}");
                writer.WriteLine($"\tLoc Type: {varLoc.VariableLocation.VarLocType}");

                switch (varLoc.VariableLocation.VarLocType)
                {
                case VarLocType.VLT_REG:
                case VarLocType.VLT_REG_FP:
                case VarLocType.VLT_REG_BYREF:
                    writer.WriteLine($"\tRegister: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}");
                    break;

                case VarLocType.VLT_STK:
                case VarLocType.VLT_STK_BYREF:
                    writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data2}");
                    break;

                case VarLocType.VLT_REG_REG:
                    writer.WriteLine($"\tRegister 1: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"\tRegister 2: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data2)}");
                    break;

                case VarLocType.VLT_REG_STK:
                    writer.WriteLine($"\tRegister: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data2)}");
                    writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data3}");
                    break;

                case VarLocType.VLT_STK_REG:
                    writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data1}");
                    writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data2)}");
                    writer.WriteLine($"\tRegister: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data3)}");
                    break;

                case VarLocType.VLT_STK2:
                    writer.WriteLine($"\tBase Register: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"\tStack Offset: {varLoc.VariableLocation.Data2}");
                    break;

                case VarLocType.VLT_FPSTK:
                    writer.WriteLine($"\tOffset: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}");
                    break;

                case VarLocType.VLT_FIXED_VA:
                    writer.WriteLine($"\tOffset: {GetPlatformSpecificRegister(_machine, varLoc.VariableLocation.Data1)}");
                    break;

                default:
                    throw new BadImageFormatException("Unexpected var loc type");
                }

                writer.WriteLine("");
            }
        }
Пример #7
0
 /// <summary>
 /// Store the R2R reader and construct the disassembler for the appropriate architecture.
 /// </summary>
 /// <param name="reader"></param>
 public Disassembler(R2RReader reader, DumpOptions options)
 {
     _reader  = reader;
     _options = options;
     _disasm  = CoreDisTools.GetDisasm(_reader.Machine);
 }
Пример #8
0
        public static void WriteTo(this RuntimeFunction theThis, TextWriter writer, DumpOptions options)
        {
            if (!options.Naked)
            {
                writer.WriteLine($"Id: {theThis.Id}");
                writer.WriteLine($"StartAddress: 0x{theThis.StartAddress:X8}");
            }
            if (theThis.Size == -1)
            {
                writer.WriteLine("Size: Unavailable");
            }
            else
            {
                writer.WriteLine($"Size: {theThis.Size} bytes");
            }
            if (!options.Naked)
            {
                writer.WriteLine($"UnwindRVA: 0x{theThis.UnwindRVA:X8}");
            }
            if (theThis.UnwindInfo is ILCompiler.Reflection.ReadyToRun.Amd64.UnwindInfo amd64UnwindInfo)
            {
                string parsedFlags = "";
                if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_EHANDLER) != 0)
                {
                    parsedFlags += " EHANDLER";
                }
                if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_UHANDLER) != 0)
                {
                    parsedFlags += " UHANDLER";
                }
                if ((amd64UnwindInfo.Flags & (int)ILCompiler.Reflection.ReadyToRun.Amd64.UnwindFlags.UNW_FLAG_CHAININFO) != 0)
                {
                    parsedFlags += " CHAININFO";
                }
                if (parsedFlags.Length == 0)
                {
                    parsedFlags = " NHANDLER";
                }
                writer.WriteLine($"Version:            {amd64UnwindInfo.Version}");
                writer.WriteLine($"Flags:              0x{amd64UnwindInfo.Flags:X2}{parsedFlags}");
                writer.WriteLine($"SizeOfProlog:       0x{amd64UnwindInfo.SizeOfProlog:X4}");
                writer.WriteLine($"CountOfUnwindCodes: {amd64UnwindInfo.CountOfUnwindCodes}");
                writer.WriteLine($"FrameRegister:      {((amd64UnwindInfo.FrameRegister == 0) ? "None" : amd64UnwindInfo.FrameRegister.ToString())}");
                writer.WriteLine($"FrameOffset:        0x{amd64UnwindInfo.FrameOffset}");
                if (!options.Naked)
                {
                    writer.WriteLine($"PersonalityRVA:     0x{amd64UnwindInfo.PersonalityRoutineRVA:X4}");
                }

                for (int uwcIndex = 0; uwcIndex < amd64UnwindInfo.UnwindCodes.Count; uwcIndex++)
                {
                    UnwindCode unwindCode = amd64UnwindInfo.UnwindCodes[uwcIndex];
                    writer.Write($"UnwindCode[{uwcIndex}]: ");
                    writer.Write($"CodeOffset 0x{unwindCode.CodeOffset:X4} ");
                    writer.Write($"FrameOffset 0x{unwindCode.FrameOffset:X4} ");
                    writer.Write($"NextOffset 0x{unwindCode.NextFrameOffset} ");
                    writer.Write($"Op {unwindCode.OpInfoStr}");
                    writer.WriteLine();
                    uwcIndex++;
                }
            }
            writer.WriteLine();

            if (theThis.EHInfo != null)
            {
                if (options.Naked)
                {
                    writer.WriteLine($@"EH info, #clauses = {theThis.EHInfo.EHClauses.Count}");
                }
                else
                {
                    writer.WriteLine($@"EH info @ {theThis.EHInfo.RelativeVirtualAddress:X4}, #clauses = {theThis.EHInfo.EHClauses.Count}");
                }
                theThis.EHInfo.WriteTo(writer, !options.Naked);
                writer.WriteLine();
            }

            if (theThis.DebugInfo != null)
            {
                theThis.DebugInfo.WriteTo(writer, options);
            }
        }
Пример #9
0
        public static void WriteTo(this DebugInfo theThis, TextWriter writer, DumpOptions dumpOptions)
        {
            if (theThis.BoundsList.Count > 0)
            {
                writer.WriteLine("Debug Info");
            }

            writer.WriteLine("    Bounds:");
            for (int i = 0; i < theThis.BoundsList.Count; ++i)
            {
                writer.Write("    ");
                if (!dumpOptions.Naked)
                {
                    writer.Write($"Native Offset: 0x{theThis.BoundsList[i].NativeOffset:X}, ");
                }
                if (theThis.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.NoMapping)
                {
                    writer.WriteLine($"NoMapping, Source Types: {theThis.BoundsList[i].SourceTypes}");
                }
                else if (theThis.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.Prolog)
                {
                    writer.WriteLine($"Prolog, Source Types: {theThis.BoundsList[i].SourceTypes}");
                }
                else if (theThis.BoundsList[i].ILOffset == (uint)DebugInfoBoundsType.Epilog)
                {
                    writer.WriteLine($"Epilog, Source Types: {theThis.BoundsList[i].SourceTypes}");
                }
                else
                {
                    writer.WriteLine($"IL Offset: 0x{theThis.BoundsList[i].ILOffset:x4}, Source Types: {theThis.BoundsList[i].SourceTypes}");
                }
            }
            writer.WriteLine("");

            if (dumpOptions.Normalize)
            {
                theThis.VariablesList.Sort(new NativeVarInfoComparer());
            }

            if (theThis.VariablesList.Count > 0)
            {
                writer.WriteLine("    Variable Locations:");
            }

            for (int i = 0; i < theThis.VariablesList.Count; ++i)
            {
                var varLoc = theThis.VariablesList[i];
                writer.WriteLine($"    Variable Number: {varLoc.VariableNumber}");
                writer.WriteLine($"    Start Offset: 0x{varLoc.StartOffset:X}");
                writer.WriteLine($"    End Offset: 0x{varLoc.EndOffset:X}");
                writer.WriteLine($"    Loc Type: {varLoc.VariableLocation.VarLocType}");

                switch (varLoc.VariableLocation.VarLocType)
                {
                case VarLocType.VLT_REG:
                case VarLocType.VLT_REG_FP:
                case VarLocType.VLT_REG_BYREF:
                    writer.WriteLine($"    Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}");
                    break;

                case VarLocType.VLT_STK:
                case VarLocType.VLT_STK_BYREF:
                    writer.WriteLine($"    Base Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"    Stack Offset: {varLoc.VariableLocation.Data2}");
                    break;

                case VarLocType.VLT_REG_REG:
                    writer.WriteLine($"    Register 1: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"    Register 2: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data2)}");
                    break;

                case VarLocType.VLT_REG_STK:
                    writer.WriteLine($"    Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"    Base Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data2)}");
                    writer.WriteLine($"    Stack Offset: {varLoc.VariableLocation.Data3}");
                    break;

                case VarLocType.VLT_STK_REG:
                    writer.WriteLine($"    Stack Offset: {varLoc.VariableLocation.Data1}");
                    writer.WriteLine($"    Base Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data2)}");
                    writer.WriteLine($"    Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data3)}");
                    break;

                case VarLocType.VLT_STK2:
                    writer.WriteLine($"    Base Register: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}");
                    writer.WriteLine($"    Stack Offset: {varLoc.VariableLocation.Data2}");
                    break;

                case VarLocType.VLT_FPSTK:
                    writer.WriteLine($"    Offset: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}");
                    break;

                case VarLocType.VLT_FIXED_VA:
                    writer.WriteLine($"    Offset: {DebugInfo.GetPlatformSpecificRegister(theThis.Machine, varLoc.VariableLocation.Data1)}");
                    break;

                default:
                    throw new BadImageFormatException("Unexpected var loc type");
                }

                writer.WriteLine("");
            }
        }
Пример #10
0
 public static void WriteTo(this ReadyToRunSection theThis, TextWriter writer, DumpOptions options)
 {
     writer.WriteLine($"Type:  {Enum.GetName(typeof(ReadyToRunSectionType), theThis.Type)} ({theThis.Type:D})");
     if (!options.Naked)
     {
         writer.WriteLine($"RelativeVirtualAddress: 0x{theThis.RelativeVirtualAddress:X8}");
     }
     writer.WriteLine($"Size: {theThis.Size} bytes");
 }
Пример #11
0
 public static void WriteTo(this ReadyToRunImportSection.ImportSectionEntry theThis, TextWriter writer, DumpOptions options)
 {
     if (!options.Naked)
     {
         writer.Write($"+{theThis.StartOffset:X4}");
         writer.Write($" ({theThis.StartRVA:X4})");
         writer.Write($"  Section: 0x{theThis.Section:X8}");
         writer.Write($"  SignatureRVA: 0x{theThis.SignatureRVA:X8}");
         writer.Write("   ");
     }
     writer.Write(theThis.Signature.ToString(options.GetSignatureFormattingOptions()));
     if (theThis.GCRefMap != null)
     {
         writer.Write(" -- ");
         theThis.GCRefMap.WriteTo(writer);
     }
 }
Пример #12
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(DumpOptions options, string filename)
        {
            Options  = options;
            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) != 0);
                if (!IsR2R)
                {
                    throw new BadImageFormatException("The file is not a ReadyToRun image");
                }

                uint machine = (uint)PEReader.PEHeaders.CoffHeader.Machine;

                OS = OperatingSystem.Unknown;
                foreach (OperatingSystem os in Enum.GetValues(typeof(OperatingSystem)))
                {
                    Machine = (Machine)(machine ^ (uint)os);
                    if (Enum.IsDefined(typeof(Machine), Machine))
                    {
                        OS = os;
                        break;
                    }
                }
                if (OS == OperatingSystem.Unknown)
                {
                    throw new BadImageFormatException($"Invalid Machine: {machine}");
                }

                switch (Machine)
                {
                case Machine.I386:
                    Architecture = Architecture.X86;
                    PointerSize  = 4;
                    break;

                case Machine.Amd64:
                    Architecture = Architecture.X64;
                    PointerSize  = 8;
                    break;

                case Machine.Arm:
                case Machine.Thumb:
                case Machine.ArmThumb2:
                    Architecture = Architecture.Arm;
                    PointerSize  = 4;
                    break;

                case Machine.Arm64:
                    Architecture = Architecture.Arm64;
                    PointerSize  = 8;
                    break;

                default:
                    throw new NotImplementedException(Machine.ToString());
                }


                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");
                }

                if (PEReader.HasMetadata)
                {
                    MetadataReader = PEReader.GetMetadataReader();

                    ParseDebugInfo();

                    if (R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_EXCEPTION_INFO))
                    {
                        R2RSection exceptionInfoSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_EXCEPTION_INFO];
                        EHLookupTable = new EHLookupTable(Image, GetOffset(exceptionInfoSection.RelativeVirtualAddress), exceptionInfoSection.Size);
                    }

                    ImportSections  = new List <R2RImportSection>();
                    ImportCellNames = new Dictionary <int, string>();
                    ParseImportSections();

                    R2RMethods      = new List <R2RMethod>();
                    InstanceMethods = new List <InstanceMethod>();

                    if (R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS))
                    {
                        int        runtimeFunctionSize    = CalculateRuntimeFunctionSize();
                        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];

                        // initialize R2RMethods
                        ParseMethodDefEntrypoints(isEntryPoint);
                        ParseInstanceMethodEntrypoints(isEntryPoint);
                        ParseRuntimeFunctions(isEntryPoint, runtimeFunctionOffset, runtimeFunctionSize);
                    }

                    AvailableTypes = new List <string>();
                    ParseAvailableTypes();

                    CompilerIdentifier = ParseCompilerIdentifier();
                }
            }
        }