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); }
public Dumper(ReadyToRunReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options) { _r2r = r2r; _writer = writer; _disassembler = disassembler; _options = options; }
public TextDumper(ReadyToRunReader r2r, TextWriter writer, Disassembler disassembler, DumpOptions options) : base(r2r, writer, disassembler, options) { }
/// <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(); }
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); } }
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(""); } }
/// <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); }
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); } }
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(""); } }
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"); }
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); } }
/// <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(); } } }