/// <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) != 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}"); } 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); } R2RMethods = new List <R2RMethod>(); 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(); ImportSections = new List <R2RImportSection>(); ImportCellNames = new Dictionary <int, string>(); ParseImportSections(); } } }
/// <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(); }