Exemplo n.º 1
0
        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());
                }
            }
        }
Exemplo n.º 2
0
 public DotNetHeadersImpl(PeHeaders peHeaders, DotNetCor20Data cor20, DotNetMetadataHeaders metadataHeaders, VirtualArrayData <ByteData> strongNameSignature, DotNetMethodProvider methodProvider, DotNetResourceProvider resourceProvider)
 {
     if (peHeaders == null)
     {
         throw new ArgumentNullException(nameof(peHeaders));
     }
     if (cor20 == null)
     {
         throw new ArgumentNullException(nameof(cor20));
     }
     if (methodProvider == null)
     {
         throw new ArgumentNullException(nameof(methodProvider));
     }
     if (resourceProvider == null)
     {
         throw new ArgumentNullException(nameof(resourceProvider));
     }
     PeHeaders           = peHeaders;
     Cor20               = cor20;
     MetadataHeaders     = metadataHeaders;
     StrongNameSignature = strongNameSignature;
     MethodProvider      = methodProvider;
     ResourceProvider    = resourceProvider;
 }
Exemplo n.º 3
0
        private int ReadSecurityCookieOffset()
        {
            // Calculate the offset of the load config table

            if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.LoadConfigTableDirectory, out var loadConfigTableOffset))
            {
                return(0);
            }

            if (PeHeaders.PEHeader.Magic == PEMagic.PE32)
            {
                // Read the load config table

                var loadConfigTable = MemoryMarshal.Read <ImageLoadConfigDirectory32>(PeBytes.Slice(loadConfigTableOffset).Span);

                // Calculate the offset of the security cookie

                return(loadConfigTable.SecurityCookie == 0 ? 0 : loadConfigTable.SecurityCookie - (int)PeHeaders.PEHeader.ImageBase);
            }

            else
            {
                // Read the load config table

                var loadConfigTable = MemoryMarshal.Read <ImageLoadConfigDirectory64>(PeBytes.Slice(loadConfigTableOffset).Span);

                // Calculate the offset of the security cookie

                return(loadConfigTable.SecurityCookie == 0 ? 0 : (int)(loadConfigTable.SecurityCookie - (long)PeHeaders.PEHeader.ImageBase));
            }
        }
Exemplo n.º 4
0
 public GoToMetadataVM(HexBuffer buffer, DotNetMetadataHeaders mdHeaders, PeHeaders peHeaders, uint value)
 {
     if (buffer == null)
     {
         throw new ArgumentNullException(nameof(buffer));
     }
     if (mdHeaders == null)
     {
         throw new ArgumentNullException(nameof(mdHeaders));
     }
     this.peHeaders         = peHeaders;
     offsetTokenVM          = new OffsetTokenVM(buffer, mdHeaders, peHeaders, value, a => HasErrorUpdated());
     GoToMetadataCollection = new ObservableCollection <GoToMetadataKindVM>();
     GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.Table, dnSpy_Resources.GoToMetadataToken, dnSpy_Resources.ShortCutKeyCtrl1));
     if (peHeaders != null)
     {
         GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.MemberRva, dnSpy_Resources.GoToMetadataMethodBody, dnSpy_Resources.ShortCutKeyCtrl2));
     }
     GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.Blob, "#Blob", dnSpy_Resources.ShortCutKeyCtrl3));
     GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.Strings, "#Strings", dnSpy_Resources.ShortCutKeyCtrl4));
     GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.US, "#US", dnSpy_Resources.ShortCutKeyCtrl5));
     GoToMetadataCollection.Add(new GoToMetadataKindVM(GoToMetadataKind.GUID, "#GUID", dnSpy_Resources.ShortCutKeyCtrl6));
     selectedItem = GoToMetadataCollection[0];
     offsetTokenVM.GoToMetadataKind = GoToMetadataKind;
 }
Exemplo n.º 5
0
 void ReadStrongNameSignature(PeHeaders peHeaders, HexSpan?span)
 {
     if (span == null)
     {
         return;
     }
     strongNameSignature = ArrayData.CreateVirtualByteArray(new HexBufferSpan(file.Buffer, span.Value), name: "STRONGNAMESIGNATURE");
 }
Exemplo n.º 6
0
 void ReadDotNetMetadataHeader(PeHeaders peHeaders, HexSpan?dir)
 {
     if (dir == null)
     {
         return;
     }
     ReadDotNetMetadataHeader(dir.Value);
 }
Exemplo n.º 7
0
        internal PeParser(string dllPath)
        {
            _dllBuffer = LocalMemoryTools.StoreBytesInBuffer(File.ReadAllBytes(dllPath));

            _peHeaders = new PeHeaders();

            ReadPeHeaders();
        }
Exemplo n.º 8
0
        internal PeParser(byte[] dllBytes)
        {
            _dllBuffer = LocalMemoryTools.StoreBytesInBuffer(dllBytes);

            _peHeaders = new PeHeaders();

            ReadPeHeaders();
        }
Exemplo n.º 9
0
        internal PortableExecutableParser(string dllPath)
        {
            _dllBuffer = MemoryTools.StoreBytesInBuffer(File.ReadAllBytes(dllPath));

            _peHeaders = new PeHeaders();

            ReadHeaders();
        }
Exemplo n.º 10
0
 public OffsetTokenVM(HexBuffer buffer, DotNetMetadataHeaders mdHeaders, PeHeaders peHeaders, uint value, Action <DataFieldVM> onUpdated)
     : base(onUpdated, uint.MinValue, uint.MaxValue, null)
 {
     SetValueFromConstructor(value);
     this.buffer    = buffer;
     this.mdHeaders = mdHeaders;
     this.peHeaders = peHeaders;
 }
Exemplo n.º 11
0
        internal PortableExecutableParser(byte[] dllBytes)
        {
            _dllBuffer = MemoryTools.StoreBytesInBuffer(dllBytes);

            _peHeaders = new PeHeaders();

            ReadHeaders();
        }
Exemplo n.º 12
0
        internal PeParser(string dllPath)
        {
            _dllBufferHandle = GCHandle.Alloc(File.ReadAllBytes(dllPath), GCHandleType.Pinned);

            _dllBuffer = _dllBufferHandle.AddrOfPinnedObject();

            _peHeaders = new PeHeaders();

            ReadPeHeaders();
        }
Exemplo n.º 13
0
        internal PeParser(byte[] dllBytes)
        {
            _dllBufferHandle = GCHandle.Alloc(dllBytes.Clone(), GCHandleType.Pinned);

            _dllBuffer = _dllBufferHandle.AddrOfPinnedObject();

            _peHeaders = new PeHeaders();

            ReadPeHeaders();
        }
Exemplo n.º 14
0
 public DotNetResourceProviderImpl(HexBufferFile file, PeHeaders peHeaders, DotNetMetadataHeaders?metadataHeaders, HexSpan?resourcesSpan)
     : base(file)
 {
     this.peHeaders = peHeaders ?? throw new ArgumentNullException(nameof(peHeaders));
     if (metadataHeaders?.TablesStream is not null && resourcesSpan is not 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);
     }
Exemplo n.º 15
0
 public DotNetMethodProviderImpl(HexBufferFile file, PeHeaders peHeaders, TablesHeap tablesHeap)
     : base(file)
 {
     if (file == null)
     {
         throw new ArgumentNullException(nameof(file));
     }
     this.peHeaders   = peHeaders ?? throw new ArgumentNullException(nameof(peHeaders));
     methodBodyRvas   = CreateMethodBodyRvas(tablesHeap?.MDTables[(int)Table.Method]);
     methodBodiesSpan = GetMethodBodiesSpan(methodBodyRvas);
 }
Exemplo n.º 16
0
        private IEnumerable <BaseRelocation> ReadBaseRelocations()
        {
            // Calculate the offset of the first base relocation block

            if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.BaseRelocationTableDirectory, out var currentRelocationBlockOffset))
            {
                yield break;
            }

            while (true)
            {
                // Read the current base relocation block

                var relocationBlock = MemoryMarshal.Read <ImageBaseRelocation>(PeBytes.Slice(currentRelocationBlockOffset).Span);

                if (relocationBlock.SizeOfBlock == 0)
                {
                    yield break;
                }

                // Read the base relocations from the base relocation block

                var relocationBlockSize = (relocationBlock.SizeOfBlock - Unsafe.SizeOf <ImageBaseRelocation>()) / sizeof(short);

                var relocationBlockOffset = RvaToOffset(relocationBlock.VirtualAddress);

                for (var relocationIndex = 0; relocationIndex < relocationBlockSize; relocationIndex++)
                {
                    // Read the base relocation

                    var relocationOffset = currentRelocationBlockOffset + Unsafe.SizeOf <ImageBaseRelocation>() + sizeof(short) * relocationIndex;

                    var relocation = MemoryMarshal.Read <ushort>(PeBytes.Slice(relocationOffset).Span);

                    // The offset is located in the upper 4 bits of the base relocation

                    var offset = relocation & 0xFFF;

                    // The type is located in the lower 12 bits of the base relocation

                    var type = relocation >> 12;

                    yield return(new BaseRelocation(relocationBlockOffset + offset, (BaseRelocationType)type));
                }

                // Calculate the offset of the next base relocation block

                currentRelocationBlockOffset += relocationBlock.SizeOfBlock;
            }
        }
Exemplo n.º 17
0
        private IEnumerable <ImportDescriptor> ReadDelayImportDescriptors()
        {
            // Calculate the offset of the delay import table

            if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.DelayImportTableDirectory, out var delayImportTableOffset))
            {
                yield break;
            }

            for (var descriptorIndex = 0;; descriptorIndex++)
            {
                // Read the delay import descriptor

                var descriptorOffset = delayImportTableOffset + Unsafe.SizeOf <ImageDelayLoadDescriptor>() * descriptorIndex;

                var descriptor = MemoryMarshal.Read <ImageDelayLoadDescriptor>(PeBytes.Slice(descriptorOffset).Span);

                if (descriptor.DllNameRva == 0)
                {
                    break;
                }

                // Read the name of the delay import descriptor

                var descriptorNameOffset = RvaToOffset(descriptor.DllNameRva);

                var descriptorName = ReadNullTerminatedString(descriptorNameOffset);

                // Read the functions imported under the delay import descriptor

                var descriptorThunkOffset = RvaToOffset(descriptor.ImportNameTableRva);

                var importAddressTableOffset = RvaToOffset(descriptor.ImportAddressTableRva);

                var delayImportedFunctions = ReadDelayImportedFunctions(descriptorThunkOffset, importAddressTableOffset);

                yield return(new ImportDescriptor(delayImportedFunctions, descriptorName));
            }
        }
Exemplo n.º 18
0
        private IEnumerable <ImportDescriptor> ReadImportDescriptors()
        {
            // Calculate the import table offset

            if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.ImportTableDirectory, out var importTableOffset))
            {
                yield break;
            }

            for (var descriptorIndex = 0;; descriptorIndex++)
            {
                // Read the import descriptor

                var descriptorOffset = importTableOffset + Unsafe.SizeOf <ImageImportDescriptor>() * descriptorIndex;

                var descriptor = MemoryMarshal.Read <ImageImportDescriptor>(PeBytes.Slice(descriptorOffset).Span);

                if (descriptor.Name == 0)
                {
                    break;
                }

                // Read the import descriptor name

                var descriptorNameOffset = RvaToOffset(descriptor.Name);

                var descriptorName = ReadNullTerminatedString(descriptorNameOffset);

                // Read the functions imported under the import descriptor

                var descriptorThunkOffset = descriptor.OriginalFirstThunk == 0 ? RvaToOffset(descriptor.FirstThunk) : RvaToOffset(descriptor.OriginalFirstThunk);

                var importAddressTableOffset = RvaToOffset(descriptor.FirstThunk);

                var importedFunctions = ReadImportedFunctions(descriptorThunkOffset, importAddressTableOffset);

                yield return(new ImportDescriptor(importedFunctions, descriptorName));
            }
        }
Exemplo n.º 19
0
        HexSpan?Read(PeHeaders peHeaders, DataDirectoryData dir)
        {
            uint rva  = dir.VirtualAddress.Data.ReadValue();
            uint size = dir.Size.Data.ReadValue();

            if (rva == 0 || size == 0)
            {
                return(null);
            }
            var position = peHeaders.RvaToBufferPosition(rva);
            var end      = position + size;

            if (end > HexPosition.MaxEndPosition)
            {
                return(null);
            }
            var span = HexSpan.FromBounds(position, end);

            if (!file.Span.Contains(span))
            {
                return(null);
            }
            return(span);
        }
Exemplo n.º 20
0
        HexSpan?GetGoToMetadataSpan(DotNetMetadataHeaders mdHeaders, PeHeaders peHeaders, uint offsetTokenValue, GoToMetadataKind mdKind)
        {
            MDTable mdTable;

            switch (mdKind)
            {
            case GoToMetadataKind.Blob:
                if (mdHeaders.BlobStream == null)
                {
                    return(null);
                }
                return(new HexSpan(mdHeaders.BlobStream.Span.Span.Start + offsetTokenValue, 0));

            case GoToMetadataKind.Strings:
                if (mdHeaders.StringsStream == null)
                {
                    return(null);
                }
                return(new HexSpan(mdHeaders.StringsStream.Span.Span.Start + offsetTokenValue, 0));

            case GoToMetadataKind.US:
                if (mdHeaders.USStream == null)
                {
                    return(null);
                }
                return(new HexSpan(mdHeaders.USStream.Span.Span.Start + (offsetTokenValue & 0x00FFFFFF), 0));

            case GoToMetadataKind.GUID:
                if (mdHeaders.GUIDStream == null)
                {
                    return(null);
                }
                return(new HexSpan(mdHeaders.GUIDStream.Span.Span.Start + (offsetTokenValue - 1) * 16, 16));

            case GoToMetadataKind.Table:
                mdTable = GetMDTable(mdHeaders, offsetTokenValue);
                if (mdTable == null)
                {
                    return(null);
                }
                return(new HexSpan(mdTable.Span.Start + ((offsetTokenValue & 0x00FFFFFF) - 1) * mdTable.RowSize, mdTable.RowSize));

            case GoToMetadataKind.MemberRva:
                if (peHeaders == null)
                {
                    return(null);
                }
                mdTable = GetMDTable(mdHeaders, offsetTokenValue);
                if (mdTable == null)
                {
                    return(null);
                }
                if (mdTable.Table != Table.Method && mdTable.Table != Table.FieldRVA)
                {
                    return(null);
                }
                // Column 0 is the RVA in both Method and FieldRVA tables
                var pos = mdTable.Span.Start + ((offsetTokenValue & 0x00FFFFFF) - 1) * mdTable.RowSize;
                var rva = HexView.Buffer.ReadUInt32(pos);
                return(new HexSpan(peHeaders.RvaToBufferPosition(rva), 0));

            default: throw new InvalidOperationException();
            }
        }
Exemplo n.º 21
0
        private IEnumerable <ExportedFunction> ReadExportedFunctions()
        {
            // Calculate the offset of the export table

            if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.ExportTableDirectory, out var exportTableOffset))
            {
                yield break;
            }

            // Read the export table

            var exportTable = MemoryMarshal.Read <ImageExportDirectory>(PeBytes.Slice(exportTableOffset).Span);

            // Read the exported functions

            var functionNameBaseOffset = RvaToOffset(exportTable.AddressOfNames);

            var functionOffsetBaseOffset = RvaToOffset(exportTable.AddressOfFunctions);

            var functionOrdinalBaseOffset = RvaToOffset(exportTable.AddressOfNameOrdinals);

            for (var functionIndex = 0; functionIndex < exportTable.NumberOfNames; functionIndex++)
            {
                // Read the name of the function

                var functionNameOffsetOffset = functionNameBaseOffset + sizeof(int) * functionIndex;

                var functionNameOffset = RvaToOffset(MemoryMarshal.Read <int>(PeBytes.Slice(functionNameOffsetOffset).Span));

                var functionName = ReadNullTerminatedString(functionNameOffset);

                // Read the ordinal of the function

                var functionOrdinalOffset = functionOrdinalBaseOffset + sizeof(short) * functionIndex;

                var functionOrdinal = MemoryMarshal.Read <short>(PeBytes.Slice(functionOrdinalOffset).Span);

                // Read the offset of the function

                var functionOffsetOffset = functionOffsetBaseOffset + sizeof(int) * functionOrdinal;

                var functionOffset = MemoryMarshal.Read <int>(PeBytes.Slice(functionOffsetOffset).Span);

                // Determine if the function is forwarded to another function

                var exportTableStartOffset = PeHeaders.PEHeader.ExportTableDirectory.RelativeVirtualAddress;

                var exportTableEndOffset = exportTableStartOffset + PeHeaders.PEHeader.ExportTableDirectory.Size;

                if (functionOffset < exportTableStartOffset || functionOffset > exportTableEndOffset)
                {
                    yield return(new ExportedFunction(null, functionName, functionOffset, exportTable.Base + functionOrdinal));

                    continue;
                }

                // Read the forwarder string of the function

                var forwarderStringOffset = RvaToOffset(functionOffset);

                var forwarderString = ReadNullTerminatedString(forwarderStringOffset);

                yield return(new ExportedFunction(forwarderString, functionName, functionOffset, exportTable.Base + functionOrdinal));
            }
        }
Exemplo n.º 22
0
        private IEnumerable <int> ReadTlsCallbackOffsets()
        {
            // Calculate offset of the TLS table

            if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.ThreadLocalStorageTableDirectory, out var tlsTableOffset))
            {
                yield break;
            }

            if (PeHeaders.PEHeader.Magic == PEMagic.PE32)
            {
                // Calculate the offset of the TLS callbacks

                var tlsTable = MemoryMarshal.Read <ImageTlsDirectory32>(PeBytes.Slice(tlsTableOffset).Span);

                if (tlsTable.AddressOfCallbacks == 0)
                {
                    yield break;
                }

                var tlsCallbacksOffset = RvaToOffset(tlsTable.AddressOfCallbacks - (int)PeHeaders.PEHeader.ImageBase);

                // Read the offsets of the TLS callbacks

                for (var tlsCallbackIndex = 0;; tlsCallbackIndex++)
                {
                    var tlsCallbackVaOffset = tlsCallbacksOffset + sizeof(int) * tlsCallbackIndex;

                    var tlsCallbackVa = MemoryMarshal.Read <int>(PeBytes.Slice(tlsCallbackVaOffset).Span);

                    if (tlsCallbackVa == 0)
                    {
                        break;
                    }

                    yield return(tlsCallbackVa - (int)PeHeaders.PEHeader.ImageBase);
                }
            }

            else
            {
                // Calculate the offset of the TLS callbacks

                var tlsTable = MemoryMarshal.Read <ImageTlsDirectory64>(PeBytes.Slice(tlsTableOffset).Span);

                if (tlsTable.AddressOfCallbacks == 0)
                {
                    yield break;
                }

                var tlsCallbacksOffset = RvaToOffset((int)(tlsTable.AddressOfCallbacks - (long)PeHeaders.PEHeader.ImageBase));

                // Read the offsets of the TLS callbacks

                for (var tlsCallbackIndex = 0;; tlsCallbackIndex++)
                {
                    var tlsCallbackVaOffset = tlsCallbacksOffset + sizeof(long) * tlsCallbackIndex;

                    var tlsCallbackVa = MemoryMarshal.Read <long>(PeBytes.Slice(tlsCallbackVaOffset).Span);

                    if (tlsCallbackVa == 0)
                    {
                        break;
                    }

                    yield return((int)(tlsCallbackVa - (long)PeHeaders.PEHeader.ImageBase));
                }
            }
        }
Exemplo n.º 23
0
        public PEStructureProviderImpl(HexBufferFile file, PeHeaders peHeaders)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            if (peHeaders == null)
            {
                throw new ArgumentNullException(nameof(peHeaders));
            }
            if (peHeaders != file.GetHeaders <PeHeaders>())
            {
                throw new ArgumentException();
            }
            this.file      = file;
            this.peHeaders = peHeaders;
            var buffer = file.Buffer;

            imageDosHeader  = new ImageDosHeaderVM(buffer, peHeaders.DosHeader);
            imageFileHeader = new ImageFileHeaderVM(buffer, peHeaders.FileHeader);
            if (peHeaders.OptionalHeader.Is32Bit)
            {
                imageOptionalHeader = new ImageOptionalHeader32VM(buffer, (PeOptionalHeader32Data)peHeaders.OptionalHeader);
            }
            else
            {
                imageOptionalHeader = new ImageOptionalHeader64VM(buffer, (PeOptionalHeader64Data)peHeaders.OptionalHeader);
            }
            sections = new ImageSectionHeaderVM[peHeaders.Sections.FieldCount];
            for (int i = 0; i < sections.Length; i++)
            {
                sections[i] = new ImageSectionHeaderVM(buffer, peHeaders.Sections[i].Data);
            }
            var dnHeaders = file.GetHeaders <DotNetHeaders>();

            storageStreams = Array.Empty <StorageStreamVM>();
            if (dnHeaders != null)
            {
                imageCor20Header = new ImageCor20HeaderVM(buffer, dnHeaders.Cor20);
                var mdHeaders = dnHeaders.MetadataHeaders;
                if (mdHeaders != null)
                {
                    storageSignature = new StorageSignatureVM(buffer, mdHeaders.MetadataHeader);
                    storageHeader    = new StorageHeaderVM(buffer, mdHeaders.MetadataHeader);
                    storageStreams   = new StorageStreamVM[mdHeaders.Streams.Count];
                    for (int i = 0; i < storageStreams.Length; i++)
                    {
                        var ssh  = mdHeaders.MetadataHeader.StreamHeaders.Data[i].Data;
                        var heap = mdHeaders.Streams[i];
                        storageStreams[i] = new StorageStreamVM(buffer, heap, ssh, i);
                    }

                    var metaDataTables = new MetaDataTableVM[0x40];
                    if (mdHeaders.TablesStream != null)
                    {
                        tablesStream = new TablesStreamVM(buffer, mdHeaders.TablesStream, metaDataTables);
                        var stringsHeapSpan = GetSpan(mdHeaders.StringsStream);
                        var guidHeapSpan    = GetSpan(mdHeaders.GUIDStream);
                        foreach (var mdTable in mdHeaders.TablesStream.MDTables)
                        {
                            if (mdTable.Rows != 0)
                            {
                                metaDataTables[(int)mdTable.Table] = MetaDataTableVM.Create(buffer, tablesStream, mdTable, stringsHeapSpan, guidHeapSpan);
                            }
                        }
                    }
                }
            }
        }