USString[] CreateUSStringInfos() { var list = new List <USString>(); var pos = Span.Span.Start; var end = Span.Span.End; var buffer = Span.Buffer; while (pos < end) { var start = pos; var len = ReadCompressedUInt32(ref pos) ?? -1; if (len < 0) { pos++; continue; } if (pos + len > end) { pos++; continue; } var byteLen = len & ~1; var stringSpan = new HexSpan(pos, (ulong)byteLen); var terminalSpan = HexSpan.FromBounds(stringSpan.End, pos + len); list.Add(new USString(HexSpan.FromBounds(start, pos), stringSpan, terminalSpan)); pos = terminalSpan.End; } return(list.ToArray()); }
bool Read() { var pos = MetadataSpan.Start + 0x0C; var versionStringLength = file.Buffer.ReadUInt32(pos); var endPos = pos + 4 + versionStringLength; if (!file.Span.Contains(pos + 4) || !file.Span.Contains(endPos - 1)) { return(false); } VersionStringSpan = HexSpan.FromBounds(pos + 4, endPos); StorageSignatureSpan = HexSpan.FromBounds(MetadataSpan.Start, VersionStringSpan.End); if (!file.Span.Contains(VersionStringSpan.End + 4)) { return(false); } StorageHeaderSpan = HexSpan.FromBounds(VersionStringSpan.End, VersionStringSpan.End + 4); StreamCount = file.Buffer.ReadUInt16(StorageHeaderSpan.End - 2); StorageStreamHeaders = new StorageStreamHeader[StreamCount]; pos = StorageHeaderSpan.End; var sb = new StringBuilder(); for (int i = 0; i < StorageStreamHeaders.Length; i++) { var stream = ReadStorageStreamHeader(pos, sb); if (stream == null) { return(false); } StorageStreamHeaders[i] = stream.Value; pos = stream.Value.Span.End; } MetadataHeaderSpan = HexSpan.FromBounds(MetadataSpan.Start, pos); return(true); }
HexSpan?GetFieldReferenceSpan(HexBufferFile file, DotNetMetadataHeaderData header, HexPosition position) { if (header.StreamHeaders.Data.Span.Span.Contains(position)) { var stream = (DotNetStorageStream)header.StreamHeaders.Data.GetFieldByPosition(position).Data; if (stream.Offset.Data.Span.Span.Contains(position)) { uint offset = stream.Offset.Data.ReadValue(); uint size = stream.Size.Data.ReadValue(); var pos = header.Span.Span.Start + offset; if (pos >= file.Span.End) { return(null); } var mdHeaders = file.GetHeaders <DotNetMetadataHeaders>(); if (mdHeaders == null) { return(new HexSpan(pos, 0)); } if (pos >= mdHeaders.MetadataSpan.End) { return(null); } var end = pos + size; if (end > mdHeaders.MetadataSpan.End) { return(new HexSpan(pos, 0)); } return(HexSpan.FromBounds(pos, end)); } return(null); } return(null); }
protected IEnumerable <HexSpan> GetValidSpansReverse(HexBuffer buffer, HexPosition start, HexPosition lowerBounds) { var pos = start; bool fullSpan = true; for (;;) { var span = buffer.GetPreviousValidSpan(pos, lowerBounds, fullSpan); if (span == null) { break; } var newStart = HexPosition.Max(lowerBounds, span.Value.Start); var newEnd = HexPosition.Min(pos + 1, span.Value.End); if (newStart < newEnd) { yield return(HexSpan.FromBounds(newStart, newEnd)); } if (span.Value.Start == 0) { break; } pos = span.Value.Start - 1; fullSpan = false; } }
MethodBodyInfo ParseMethodBody(int nextMethodIndex, IList <uint> tokens, HexPosition methodBodyPosition) { uint maxMethodBodyEndRva; HexPosition endPos; if (nextMethodIndex >= methodBodyRvas.Length) { maxMethodBodyEndRva = (uint)Math.Min(uint.MaxValue, (ulong)methodBodyRvas[methodBodyRvas.Length - 1].Rva + 1); endPos = File.Span.End; } else { maxMethodBodyEndRva = methodBodyRvas[nextMethodIndex].Rva; endPos = HexPosition.Min(File.Span.End, peHeaders.RvaToBufferPosition(maxMethodBodyEndRva)); } if (endPos < methodBodyPosition) { endPos = methodBodyPosition; } var info = new MethodBodyReader(File, tokens, methodBodyPosition, endPos).Read(); if (info != null) { return(info.Value); } // The file could be obfuscated (encrypted methods), assume the method ends at the next method body RVA endPos = HexPosition.Min(File.Span.End, peHeaders.RvaToBufferPosition(maxMethodBodyEndRva)); if (endPos < methodBodyPosition) { endPos = methodBodyPosition; } return(new MethodBodyInfo(tokens, HexSpan.FromBounds(methodBodyPosition, endPos), HexSpan.FromBounds(endPos, endPos), default(HexSpan), MethodBodyInfoFlags.Invalid)); }
static HexSpan GetDefaultSpan(IntPtr hProcess) { int bitness = GetBitness(hProcess); if (bitness == 32) { return(HexSpan.FromBounds(0, uint.MaxValue + 1UL)); } if (bitness == 64) { // If we're a 32-bit process, we can't read anything >= 2^32 from the other process // so return span [0,2^32) if (IntPtr.Size != 8) { return(HexSpan.FromBounds(0, new HexPosition(uint.MaxValue + 1UL))); } NativeMethods.GetSystemInfo(out var info); var lastAddr = (ulong)info.lpMaximumApplicationAddress.ToInt64(); // Include the last part so we get a nice even address if ((lastAddr & 0xFFFFF) == 0xEFFFF) { lastAddr += 0x10000; } return(HexSpan.FromBounds(0, new HexPosition(lastAddr) + 1)); } Debug.Fail($"Unsupported bitness: {bitness}"); return(HexSpan.FromBounds(0, HexPosition.MaxEndPosition)); }
/// <summary> /// Constructor /// </summary> /// <param name="buffer">Buffer</param> /// <param name="stringSpan">Span of string, not including the terminating zero</param> /// <param name="hasTerminatingZero">true if there's a terminating zero, false if there's no terminating zero /// or if the string is too long</param> /// <param name="heap">Owner heap</param> /// <param name="tokens">Tokens of records referencing this string</param> public StringsHeapRecordData(HexBuffer buffer, HexSpan stringSpan, bool hasTerminatingZero, StringsHeap heap, uint[] tokens) : base(NAME, new HexBufferSpan(buffer, HexSpan.FromBounds(stringSpan.Start, stringSpan.End + (hasTerminatingZero ? 1 : 0)))) { if (tokens == null) { throw new ArgumentNullException(nameof(tokens)); } Heap = heap ?? throw new ArgumentNullException(nameof(heap)); Tokens = new ReadOnlyCollection <uint>(tokens); String = new StructField <StringData>("String", new StringData(new HexBufferSpan(buffer, stringSpan), Encoding.UTF8)); if (hasTerminatingZero) { Terminator = new StructField <ByteData>("Terminator", new ByteData(buffer, stringSpan.End)); } if (Terminator != null) { Fields = new BufferField[] { String, Terminator, }; } else { Fields = new BufferField[] { String, }; } }
public DotNetResourceProviderImpl(HexBufferFile file, PeHeaders peHeaders, DotNetMetadataHeaders metadataHeaders, HexSpan?resourcesSpan) : base(file) { this.peHeaders = peHeaders ?? throw new ArgumentNullException(nameof(peHeaders)); if (metadataHeaders?.TablesStream != null && resourcesSpan != null) { Debug.Assert(file.Span.Contains(resourcesSpan.Value)); // Verified by caller ResourcesSpan = resourcesSpan.Value; resourceInfos = CreateResourceInfos(file, metadataHeaders.TablesStream.MDTables[(int)Table.ManifestResource], metadataHeaders.StringsStream); } else { resourceInfos = Array.Empty <ResourceInfo>(); } if (resourceInfos.Length > 0) { var lastEnd = resourceInfos[0].Span.Start; var filesToCreate = new List <BufferFileOptions>(); foreach (var info in resourceInfos) { if (info.Span.Start < lastEnd) { continue; } filesToCreate.Add(new BufferFileOptions(HexSpan.FromBounds(info.Span.Start + 4, info.Span.End), info.FilteredName, string.Empty, defaultTags)); lastEnd = info.Span.End; } if (filesToCreate.Count > 0) { file.CreateFiles(filesToCreate.ToArray()); } } }
public override HexSpanInfo GetSpanInfo(HexPosition position) { CheckDisposed(); if (position >= HexPosition.MaxEndPosition) { throw new ArgumentOutOfRangeException(nameof(position)); } return(stream?.GetSpanInfo(position) ?? new HexSpanInfo(HexSpan.FromBounds(HexPosition.Zero, HexPosition.MaxEndPosition), HexSpanInfoFlags.None)); }
public void Invalidate(NormalizedHexChangeCollection changes) { if (changes.Count == 0) { return; } var span = HexSpan.FromBounds(changes[0].OldSpan.Start, changes[changes.Count - 1].OldSpan.End); Invalidate(span); }
HexSpan?TryGetSpan(FatMethodBody fatBody, uint offset, uint length) { var pos = fatBody.Instructions.Data.Span.Span.Start + offset; var end = pos + length; if (end > fatBody.Instructions.Data.Span.Span.End) { return(null); } return(HexSpan.FromBounds(pos, end)); }
/// <summary> /// Constructor /// </summary> /// <param name="resourceProvider">Owner</param> /// <param name="buffer">Buffer</param> /// <param name="lengthSpan">Span of 7-bit encoded length</param> /// <param name="stringSpan">Span of string data</param> public MultiResourceUnicodeNameAndOffsetData(DotNetMultiFileResources resourceProvider, HexBuffer buffer, HexSpan lengthSpan, HexSpan stringSpan) : base(NAME, new HexBufferSpan(buffer, HexSpan.FromBounds(lengthSpan.Start, stringSpan.End + 4))) { ResourceProvider = resourceProvider ?? throw new ArgumentNullException(nameof(resourceProvider)); ResourceName = new StructField <Bit7EncodedStringData>("ResourceName", new Bit7EncodedStringData(buffer, lengthSpan, stringSpan, Encoding.Unicode)); DataOffset = new StructField <UInt32Data>("DataOffset", new UInt32Data(buffer, stringSpan.End)); Fields = new BufferField[] { ResourceName, DataOffset, }; }
public unsafe override HexSpanInfo GetSpanInfo(HexPosition position) { if (position >= HexPosition.MaxEndPosition) { throw new ArgumentOutOfRangeException(nameof(position)); } if (position >= endAddress) { return(new HexSpanInfo(HexSpan.FromBounds(endAddress, HexPosition.MaxEndPosition), HexSpanInfoFlags.None)); } ulong baseAddress, regionSize; uint state, protect; int res; if (IntPtr.Size == 4) { NativeMethods.MEMORY_BASIC_INFORMATION32 info; res = NativeMethods.VirtualQueryEx32(hProcess, new IntPtr((void *)position.ToUInt64()), out info, NativeMethods.MEMORY_BASIC_INFORMATION32_SIZE); baseAddress = info.BaseAddress; regionSize = info.RegionSize; state = info.State; protect = info.Protect; Debug.Assert(res == 0 || res == NativeMethods.MEMORY_BASIC_INFORMATION32_SIZE); } else { NativeMethods.MEMORY_BASIC_INFORMATION64 info; res = NativeMethods.VirtualQueryEx64(hProcess, new IntPtr((void *)position.ToUInt64()), out info, NativeMethods.MEMORY_BASIC_INFORMATION64_SIZE); baseAddress = info.BaseAddress; regionSize = info.RegionSize; state = info.State; protect = info.Protect; Debug.Assert(res == 0 || res == NativeMethods.MEMORY_BASIC_INFORMATION64_SIZE); } // Could fail if eg. the process has exited if (res == 0) { return(new HexSpanInfo(HexSpan.FromBounds(HexPosition.Zero, endAddress), HexSpanInfoFlags.None)); } var flags = HexSpanInfoFlags.None; if (state == NativeMethods.MEM_COMMIT) { uint access = protect & 0xFF; if (access != NativeMethods.PAGE_NOACCESS && (protect & NativeMethods.PAGE_GUARD) == 0) { flags |= HexSpanInfoFlags.HasData; } } return(new HexSpanInfo(new HexSpan(baseAddress, regionSize), flags)); }
HexSpan?GetFieldReferenceSpan(HexBufferFile file, TableRecordData record, HexPosition position) { if (record.Token.Table == Table.ManifestResource) { var recordOffset = (position - record.Span.Span.Start).ToUInt64(); // Check if it's not Offset column if (recordOffset >= 4) { return(null); } var mdTable = record.TablesHeap.MDTables[(int)Table.ManifestResource]; Debug.Assert(mdTable.IsValidRID(record.Token.Rid)); if (!mdTable.IsValidRID(record.Token.Rid)) { return(null); } var recordPos = mdTable.Span.Start + (record.Token.Rid - 1) * mdTable.RowSize; var buffer = file.Buffer; uint offset = buffer.ReadUInt32(recordPos); uint implementation = mdTable.TableInfo.Columns[3].Size == 2 ? buffer.ReadUInt16(recordPos + mdTable.RowSize - 2) : buffer.ReadUInt32(recordPos + mdTable.RowSize - 4); MDToken implementationToken; if (!CodedToken.Implementation.Decode(implementation, out implementationToken)) { return(null); } if (implementationToken.Rid != 0) { return(null); } var resources = file.GetHeaders <DotNetHeaders>()?.ResourceProvider; if (resources == null) { return(null); } if (offset >= resources.ResourcesSpan.Length) { return(null); } var pos = resources.ResourcesSpan.Start + offset; uint size = pos + 4 > resources.ResourcesSpan.End ? 0 : buffer.ReadUInt32(pos); var end = (pos + 4) + size; if (end > resources.ResourcesSpan.End) { return(new HexSpan(pos, 0)); } return(HexSpan.FromBounds(pos, end)); } return(null); }
public MetaDataTableNode(HexBuffer buffer, MDTable mdTable, IMetaData md) : base(HexSpan.FromBounds((ulong)mdTable.StartOffset, (ulong)mdTable.EndOffset)) { Buffer = buffer; TableInfo = mdTable.TableInfo; var stringsHeapSpan = HexSpan.FromBounds((ulong)md.StringsStream.StartOffset, (ulong)md.StringsStream.EndOffset); var guidHeapSpan = HexSpan.FromBounds((ulong)md.GuidStream.StartOffset, (ulong)md.GuidStream.EndOffset); MetaDataTableVM = MetaDataTableVM.Create(this, buffer, Span.Start, mdTable, stringsHeapSpan, guidHeapSpan); MetaDataTableVM.FindMetaDataTable = FindMetaDataTable; }
KnownStringInfo[] CreateKnownStringInfos(TablesHeap?tables) { if (tables is null) { return(Array.Empty <KnownStringInfo>()); } var dict = new Dictionary <uint, List <uint> >(); dict[0] = new List <uint>(); foreach (var info in tableInitInfos) { if (info.Column2 >= 0) { Add(dict, tables.MDTables[(int)info.Table], info.Column1, info.Column2); } else { Add(dict, tables.MDTables[(int)info.Table], info.Column1); } } var list = new List <(uint pos, uint[] tokens)>(dict.Count); foreach (var kv in dict) { list.Add((kv.Key, kv.Value.ToArray())); } list.Sort((a, b) => a.pos.CompareTo(b.pos)); var infos = new KnownStringInfo[list.Count]; var start = Span.Span.Start; var end = Span.Span.End; int i; for (i = 0; i < infos.Length; i++) { var kv = list[i]; var pos = start + kv.pos; if (pos >= end) { break; } var span = HexSpan.FromBounds(pos, i + 1 < list.Count ? start + list[i + 1].pos : end); infos[i] = new KnownStringInfo(span, kv.tokens); } if (i != infos.Length) { Array.Resize(ref infos, i); } return(infos); }
HexSpan GetMethodBodiesSpan(MethodBodyRvaAndRid[] methodBodyRvas) { if (methodBodyRvas.Length == 0) { return(default(HexSpan)); } int index = methodBodyRvas.Length - 1; var last = methodBodyRvas[index]; var info = ParseMethodBody(index + 1, new[] { last.Rid }, peHeaders.RvaToBufferPosition(last.Rva)); return(HexSpan.FromBounds(peHeaders.RvaToBufferPosition(methodBodyRvas[0].Rva), info.Span.End)); }
public StorageHeaderVM(HexBuffer buffer, DotNetMetadataHeaderData mdHeader) : base(HexSpan.FromBounds(mdHeader.Flags.Data.Span.Start, mdHeader.StreamCount.Data.Span.End)) { FFlagsVM = new ByteFlagsHexField(mdHeader.Flags); FFlagsVM.Add(new BooleanHexBitField(mdHeader.ExtraData.Name, 0)); PadVM = new ByteHexField(mdHeader.Pad); IStreamsVM = new UInt16HexField(mdHeader.StreamCount); hexFields = new HexField[] { FFlagsVM, PadVM, IStreamsVM, }; }
public TablesStreamNode(HexBuffer buffer, TablesStream tblStream, IMetaData md) : base(HexSpan.FromBounds((ulong)tblStream.StartOffset, (ulong)tblStream.MDTables[0].StartOffset)) { tablesStreamVM = new TablesStreamVM(this, buffer, tblStream); newChildren = new List <TreeNodeData>(); foreach (var mdTable in tblStream.MDTables) { if (mdTable.Rows != 0) { newChildren.Add(new MetaDataTableNode(buffer, mdTable, md)); } } }
/// <summary> /// Constructor /// </summary> /// <param name="buffer">Buffer</param> /// <param name="lengthSpan">Span of length</param> /// <param name="stringSpan">Span of string data</param> /// <param name="encoding">Encoding</param> public Bit7EncodedStringData(HexBuffer buffer, HexSpan lengthSpan, HexSpan stringSpan, Encoding encoding) : base(NAME, new HexBufferSpan(buffer, HexSpan.FromBounds(lengthSpan.Start, stringSpan.End))) { if (lengthSpan.End != stringSpan.Start) { throw new ArgumentOutOfRangeException(nameof(stringSpan)); } Length = new StructField <Bit7EncodedInt32Data>("Length", new Bit7EncodedInt32Data(new HexBufferSpan(buffer, lengthSpan))); String = new StructField <StringData>("String", new StringData(new HexBufferSpan(buffer, stringSpan), encoding)); Fields = new BufferField[] { Length, String, }; }
public StorageStreamNode(HexBuffer buffer, StreamHeader sh, int streamNumber, DotNetStream knownStream, IMetaData md) : base(HexSpan.FromBounds((ulong)sh.StartOffset, (ulong)sh.EndOffset)) { StreamNumber = streamNumber; StorageStreamType = GetStorageStreamType(knownStream); storageStreamVM = new StorageStreamVM(this, buffer, Span.Start, (int)(Span.Length - 8).ToUInt64()); var tblStream = knownStream as TablesStream; if (tblStream != null) { newChild = new TablesStreamNode(buffer, tblStream, md); } }
public override void Execute(ModulesCtxMenuContext context) { var vm = GetModule(context); if (vm != null) { var start = new HexPosition(vm.Module.Address); var end = start + vm.Module.Size; Debug.Assert(end <= HexPosition.MaxEndPosition); if (end <= HexPosition.MaxEndPosition) { memoryWindowService.Value.Show(HexSpan.FromBounds(start, end), windowIndex); } } }
StringZ GetStringSpan(HexPosition position, HexPosition end) { var pos = position; var buffer = Span.Buffer; while (pos < end) { if (buffer.ReadByte(pos) == 0) { return(new StringZ(HexSpan.FromBounds(position, pos), 1)); } pos++; } return(new StringZ(HexSpan.FromBounds(position, pos), 0)); }
ComplexData?GetStructure(BlobDataInfo info, HexPosition position) { var pos = info.Span.Start; var lengthStart = pos; var len = ReadCompressedUInt32(ref pos) ?? -1; if (len < 0) { return(null); } if (pos + len > Span.Span.End) { return(null); } var lengthSpan = HexSpan.FromBounds(lengthStart, pos); var dataSpan = new HexSpan(lengthSpan.End, (ulong)len); var fullSpan = HexSpan.FromBounds(lengthSpan.Start, dataSpan.End); if (!fullSpan.Contains(position)) { return(null); } switch (info.Kind) { case BlobDataKind.None: case BlobDataKind.TypeSignature: case BlobDataKind.Signature: case BlobDataKind.Constant: case BlobDataKind.CustomAttribute: case BlobDataKind.NativeType: case BlobDataKind.PermissionSet: case BlobDataKind.PublicKey: case BlobDataKind.PublicKeyOrToken: case BlobDataKind.HashValue: case BlobDataKind.Utf8Name: case BlobDataKind.Name: case BlobDataKind.SequencePoints: case BlobDataKind.LocalConstantSig: case BlobDataKind.Imports: case BlobDataKind.CustomDebugInformationValue: var varray = ArrayData.CreateVirtualByteArray(new HexBufferSpan(Span.Buffer, dataSpan)); return(new BlobHeapRecordData(Span.Buffer, fullSpan, lengthSpan, varray, info.Tokens, this)); default: throw new InvalidOperationException(); } }
/// <summary> /// Constructor /// </summary> /// <param name="resourceProvider">Owner</param> /// <param name="resourceInfo">Resource info</param> /// <param name="span">Span</param> /// <param name="lengthPosition">Position of 32-bit content length which immediately follows the 7-bit encoded type code</param> public MultiResourceArrayDataHeaderData(DotNetMultiFileResources resourceProvider, MultiResourceInfo resourceInfo, HexBufferSpan span, HexPosition lengthPosition) : base(resourceProvider, resourceInfo, span) { var typeCodeSpan = new HexBufferSpan(span.Buffer, HexSpan.FromBounds(span.Start, lengthPosition)); TypeCode = new StructField <ResourceTypeCodeData>("TypeCode", ResourceTypeCodeData.Create(typeCodeSpan)); ContentLength = new StructField <UInt32Data>("ContentLength", new UInt32Data(span.Buffer, lengthPosition)); var arraySpan = new HexBufferSpan(span.Buffer, HexSpan.FromBounds(lengthPosition + 4, span.End)); Content = new StructField <VirtualArrayData <ByteData> >("Content", ArrayData.CreateVirtualByteArray(arraySpan)); Fields = new BufferField[] { TypeCode, ContentLength, Content, }; }
public MethodBodyInfo?Read() { currentPosition = methodBodyPosition; if (!ReadHeader()) { return(null); } var headerSpan = HexSpan.FromBounds(methodBodyPosition, currentPosition); var instructionsSpan = new HexSpan(currentPosition, codeSize); currentPosition += codeSize; var exceptionsSpan = ReadExceptionHandlers(out bool isSmallExceptionClauses); return(new MethodBodyInfo(tokens, headerSpan, instructionsSpan, exceptionsSpan, isSmallExceptionClauses ? MethodBodyInfoFlags.SmallExceptionClauses : MethodBodyInfoFlags.None)); }
HexSpan?GetResourceSpan(HexBuffer buffer, uint offset) { var start = ResourcesSpan.Start + offset; if (start + 4 > ResourcesSpan.End) { return(null); } uint size = buffer.ReadUInt32(start); var end = start + 4 + size; if (end > ResourcesSpan.End) { return(null); } return(HexSpan.FromBounds(start, end)); }
/// <summary> /// Gets the span of the string, not including the terminating zero byte. /// Returns an empty span if <paramref name="offset"/> is invalid. /// </summary> /// <param name="offset">Offset</param> /// <param name="maxByteLength">Maximum number of bytes to read</param> /// <returns></returns> public HexBufferSpan GetStringSpan(uint offset, int maxByteLength) { var start = Span.Span.Start + offset; var pos = start; var buffer = Span.Buffer; var end = HexPosition.Min(Span.Span.End, start + maxByteLength); while (pos < end && buffer.ReadByte(pos) != 0) { pos++; } if (start <= pos) { return(new HexBufferSpan(buffer, HexSpan.FromBounds(start, pos))); } return(new HexBufferSpan(buffer, Span.Span.Start, 0)); }
PEStructure(PEStructureProvider peStructureProvider) { this.peStructureProvider = peStructureProvider; var list = new List <HexVM> { peStructureProvider.ImageDosHeader, peStructureProvider.ImageFileHeader, peStructureProvider.ImageOptionalHeader, }; if (peStructureProvider.ImageCor20Header is not null) { list.Add(peStructureProvider.ImageCor20Header); } if (peStructureProvider.StorageSignature is not null) { list.Add(peStructureProvider.StorageSignature); } if (peStructureProvider.StorageHeader is not null) { list.Add(peStructureProvider.StorageHeader); } if (peStructureProvider.TablesStream is not null) { list.Add(peStructureProvider.TablesStream); } list.AddRange(peStructureProvider.Sections); list.AddRange(peStructureProvider.StorageStreams); hexStructures = list.ToArray(); var tblsStream = peStructureProvider.TablesStream; if (tblsStream is not null) { var first = tblsStream.MetadataTables.FirstOrDefault(a => a is not null); var last = tblsStream.MetadataTables.LastOrDefault(a => a is not null); Debug2.Assert(first is not null); if (first is not null) { Debug2.Assert(last is not null); metadataTablesSpan = HexSpan.FromBounds(first.Span.Start, last.Span.End); } } }
public StorageSignatureVM(HexBuffer buffer, DotNetMetadataHeaderData mdHeader) : base(HexSpan.FromBounds(mdHeader.Span.Start, mdHeader.VersionString.Data.Span.End)) { LSignatureVM = new UInt32HexField(mdHeader.Signature); IMajorVerVM = new UInt16HexField(mdHeader.MajorVersion, true); IMinorVerVM = new UInt16HexField(mdHeader.MinorVersion, true); IExtraDataVM = new UInt32HexField(mdHeader.ExtraData); IVersionStringVM = new UInt32HexField(mdHeader.VersionStringCount); VersionStringVM = new StringHexField(mdHeader.VersionString); hexFields = new HexField[] { LSignatureVM, IMajorVerVM, IMinorVerVM, IExtraDataVM, IVersionStringVM, VersionStringVM, }; }