public static IntPtr GetDisasm(Machine machine) { TargetArch target = TargetArch.Target_Host; switch (machine) { case Machine.Amd64: target = TargetArch.Target_X64; break; case Machine.I386: target = TargetArch.Target_X86; break; case Machine.Arm64: target = TargetArch.Target_Arm64; break; case Machine.ArmThumb2: target = TargetArch.Target_Thumb; break; default: R2RDump.WriteWarning($"{machine} not supported on CoreDisTools"); return(IntPtr.Zero); } return(InitBufferedDisasm(target)); }
public virtual string GetGenericTypeParameter(DisassemblingGenericContext genericContext, int index) { if (index >= genericContext.TypeParameters.Length) { R2RDump.WriteWarning("GenericTypeParameter index out of bounds"); return(""); } return(genericContext.TypeParameters[index]); }
/// <summary> /// Iterates through a native hashtable to get all RIDs /// </summary> private void ParseAvailableTypes() { if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES)) { return; } HashSet <uint> added = new HashSet <uint>(); R2RSection availableTypesSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES]; int availableTypesOffset = GetOffset(availableTypesSection.RelativeVirtualAddress); NativeParser parser = new NativeParser(Image, (uint)availableTypesOffset); NativeHashtable availableTypes = new NativeHashtable(Image, parser, (uint)(availableTypesOffset + availableTypesSection.Size)); NativeHashtable.AllEntriesEnumerator allEntriesEnum = availableTypes.EnumerateAllEntries(); NativeParser curParser = allEntriesEnum.GetNext(); while (!curParser.IsNull()) { uint rid = curParser.GetUnsigned(); rid = rid >> 1; if (added.Contains(rid)) { continue; } TypeDefinitionHandle typeDefHandle = MetadataTokens.TypeDefinitionHandle((int)rid); string typeDefName = MetadataNameFormatter.FormatHandle(MetadataReader, typeDefHandle); ExportedTypeHandle exportedTypeHandle = MetadataTokens.ExportedTypeHandle((int)rid); string exportedTypeName = GetExportedTypeFullName(MetadataReader, exportedTypeHandle); if (typeDefName == null && exportedTypeName == null) { R2RDump.WriteWarning($"AvailableType with rid {rid} is not a TypeDef or ExportedType"); } if (typeDefName != null) { AvailableTypes.Add(typeDefName); added.Add(rid); } if (exportedTypeName != null) { AvailableTypes.Add("exported " + exportedTypeName); added.Add(rid); } curParser = allEntriesEnum.GetNext(); } }
/// <summary> /// Initializes the fields of the R2RHeader /// </summary> /// <param name="image">PE image</param> /// <param name="rva">Relative virtual address of the ReadyToRun header</param> /// <param name="curOffset">Index in the image byte array to the start of the ReadyToRun header</param> /// <exception cref="BadImageFormatException">The signature must be 0x00525452</exception> public R2RHeader(byte[] image, int rva, int curOffset) { RelativeVirtualAddress = rva; int startOffset = curOffset; byte[] signature = new byte[sizeof(uint)]; Array.Copy(image, curOffset, signature, 0, sizeof(uint)); SignatureString = System.Text.Encoding.UTF8.GetString(signature); Signature = NativeReader.ReadUInt32(image, ref curOffset); if (Signature != READYTORUN_SIGNATURE) { throw new System.BadImageFormatException("Incorrect R2R header signature: " + SignatureString); } MajorVersion = NativeReader.ReadUInt16(image, ref curOffset); MinorVersion = NativeReader.ReadUInt16(image, ref curOffset); Flags = NativeReader.ReadUInt32(image, ref curOffset); int nSections = NativeReader.ReadInt32(image, ref curOffset); Sections = new Dictionary <R2RSection.SectionType, R2RSection>(); for (int i = 0; i < nSections; i++) { int type = NativeReader.ReadInt32(image, ref curOffset); var sectionType = (R2RSection.SectionType)type; if (!Enum.IsDefined(typeof(R2RSection.SectionType), type)) { R2RDump.WriteWarning("Invalid ReadyToRun section type"); } Sections[sectionType] = new R2RSection(sectionType, NativeReader.ReadInt32(image, ref curOffset), NativeReader.ReadInt32(image, ref curOffset)); } Size = curOffset - startOffset; }
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; } }
/// <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"); } Machine = _peReader.PEHeaders.CoffHeader.Machine; if (!Machine.IsDefined(typeof(Machine), Machine)) { Machine = Machine.Amd64; R2RDump.WriteWarning($"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) { _mdReader = _peReader.GetMetadataReader(); 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>(); ParseImportSections(); } } }