private NativeParser GetParserForBucket(uint bucket, out uint endOffset) { uint start, end; if (_entryIndexSize == 0) { int bucketOffset = (int)(_baseOffset + bucket); start = NativeReader.ReadByte(_image, ref bucketOffset); end = NativeReader.ReadByte(_image, ref bucketOffset); } else if (_entryIndexSize == 1) { int bucketOffset = (int)(_baseOffset + 2 * bucket); start = NativeReader.ReadUInt16(_image, ref bucketOffset); end = NativeReader.ReadUInt16(_image, ref bucketOffset); } else { int bucketOffset = (int)(_baseOffset + 4 * bucket); start = NativeReader.ReadUInt32(_image, ref bucketOffset); end = NativeReader.ReadUInt32(_image, ref bucketOffset); } endOffset = end + _baseOffset; return(new NativeParser(_image, _baseOffset + start)); }
public UnwindInfo(byte[] image, int offset) { byte versionAndFlags = NativeReader.ReadByte(image, ref offset); Version = (byte)(versionAndFlags & 7); Flags = (byte)(versionAndFlags >> 3); SizeOfProlog = NativeReader.ReadByte(image, ref offset); CountOfUnwindCodes = NativeReader.ReadByte(image, ref offset); byte frameRegisterAndOffset = NativeReader.ReadByte(image, ref offset); FrameRegister = (byte)(frameRegisterAndOffset & 15); FrameOffset = (byte)(frameRegisterAndOffset >> 4); UnwindCode = new UnwindCode[CountOfUnwindCodes]; for (int i = 0; i < CountOfUnwindCodes; i++) { UnwindCode[i] = new UnwindCode(image, ref offset); } PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset); Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode; int alignmentPad = ((Size + sizeof(int) - 1) & ~(sizeof(int) - 1)) - Size; Size += (alignmentPad + sizeof(uint)); }
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: 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) { Serialize(importSection, contentsNode); if (_raw && importSection.Entries.Count != 0) { if (importSection.SectionRVA != 0) { DumpBytes(importSection.SectionRVA, (uint)importSection.SectionSize, contentsNode, "SectionBytes"); } if (importSection.SignatureRVA != 0) { DumpBytes(importSection.SignatureRVA, (uint)importSection.Entries.Count * sizeof(int), contentsNode, "SignatureBytes"); } if (importSection.AuxiliaryDataRVA != 0) { DumpBytes(importSection.AuxiliaryDataRVA, (uint)importSection.AuxiliaryData.Size, contentsNode, "AuxiliaryDataBytes"); } } foreach (R2RImportSection.ImportSectionEntry entry in importSection.Entries) { Serialize(entry, contentsNode); } } break; } }
/// <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"); } 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.OutputWarning("Invalid ReadyToRun section type"); } Sections[sectionType] = new R2RSection(sectionType, NativeReader.ReadInt32(image, ref curOffset), NativeReader.ReadInt32(image, ref curOffset)); } Size = curOffset - startOffset; }
/// <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.IA64: 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, 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, Image, rva, size, flags, type, entrySize, signatureRVA, entries, auxDataRVA, auxDataOffset, Machine, R2RHeader.MajorVersion)); } }
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) { 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.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; } }
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)); } }
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); }