Ejemplo n.º 1
0
		public MDTableModel(MDTableHeapModel parent, IMetaData metadata, TablesStream stream, MDTable table) {
			Parent = parent;
			MetaData = metadata;
			Tables = stream;
			MDTable = table;
			Text = string.Format("{0:x2}: {1} (0x{2:x})", (byte)table.Table, table.Name, table.Rows);
		}
Ejemplo n.º 2
0
		public MetaDataTableNode(HexDocument doc, MDTable mdTable, IMetaData md)
			: base((ulong)mdTable.StartOffset, (ulong)mdTable.EndOffset - 1) {
			this.doc = doc;
			this.tableInfo = mdTable.TableInfo;
			this.tablesStreamVM = MetaDataTableVM.Create(this, doc, StartOffset, mdTable);
			this.tablesStreamVM.FindMetaDataTable = FindMetaDataTable;
			this.tablesStreamVM.InitializeHeapOffsets((ulong)md.StringsStream.StartOffset, (ulong)md.StringsStream.EndOffset - 1);
		}
Ejemplo n.º 3
0
		/// <summary>
		/// Returns a reader positioned at a table row
		/// </summary>
		/// <param name="table">Table</param>
		/// <param name="rid">A valid row ID (i.e., &gt;= <c>1</c> and &lt;= number of rows)</param>
		/// <returns>The reader (owned by us) or <c>null</c> if the row isn't present</returns>
		public IImageStream GetTableReader(MDTable table, uint rid) {
			long offset;
			if (GetRowOffset(table, rid, out offset)) {
				fullStream.Position = offset;
				return fullStream;
			}

			return null;
		}
Ejemplo n.º 4
0
		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;
		}
Ejemplo n.º 5
0
		protected MetaDataTableVM(object owner, HexBuffer buffer, HexPosition startOffset, MDTable mdTable, HexSpan stringsHeapSpan, HexSpan guidHeapSpan) {
			this.buffer = buffer;
			this.stringsHeapSpan = stringsHeapSpan;
			this.guidHeapSpan = guidHeapSpan;
			Owner = owner;
			Span = new HexSpan(startOffset, (ulong)mdTable.Rows * mdTable.RowSize);
			Rows = mdTable.Rows;
			TableInfo = CreateTableInfo(mdTable.TableInfo);
			Collection = new VirtualizedList<MetaDataTableRecordVM>((int)Rows, CreateItem);
		}
Ejemplo n.º 6
0
		IBinaryReader GetReader_NoLock(MDTable table, uint rid) {
			IBinaryReader reader;
			if (hotTableStream != null) {
				reader = hotTableStream.GetTableReader(table, rid);
				if (reader != null)
					return reader;
			}
			reader = table.ImageStream;
			reader.Position = (rid - 1) * table.TableInfo.RowSize;
			return reader;
		}
Ejemplo n.º 7
0
        /// <inheritdoc/>
        protected override uint BinarySearch_NoLock(MDTable tableSource, int keyColIndex, uint key)
        {
            var keyColumn = tableSource.TableInfo.Columns[keyColIndex];
            uint ridLo = 1, ridHi = tableSource.Rows;
            while (ridLo <= ridHi) {
                uint rid = (ridLo + ridHi) / 2;
                uint key2;
                if (!tablesStream.ReadColumn_NoLock(tableSource, rid, keyColumn, out key2))
                    break;	// Never happens since rid is valid
                if (key == key2)
                    return rid;
                if (key2 > key)
                    ridHi = rid - 1;
                else
                    ridLo = rid + 1;
            }

            return 0;
        }
Ejemplo n.º 8
0
		/// <summary>
		/// Writes a <c>ModuleRef</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawModuleRefRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table)
				cols[0].Write(writer, row.Name);
		}
Ejemplo n.º 9
0
        /// <summary>
        /// Initializes MD tables
        /// </summary>
        /// <param name="peImage">The PEImage</param>
        public void Initialize(IPEImage peImage)
        {
            if (initialized)
            {
                throw new Exception("Initialize() has already been called");
            }
            initialized = true;

            reserved1    = imageStream.ReadUInt32();
            majorVersion = imageStream.ReadByte();
            minorVersion = imageStream.ReadByte();
            flags        = (MDStreamFlags)imageStream.ReadByte();
            log2Rid      = imageStream.ReadByte();
            validMask    = imageStream.ReadUInt64();
            sortedMask   = imageStream.ReadUInt64();

            int maxPresentTables;
            var dnTableSizes = new DotNetTableSizes();
            var tableInfos   = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);

            mdTables = new MDTable[tableInfos.Length];

            ulong valid = validMask;
            var   sizes = new uint[64];

            for (int i = 0; i < 64; valid >>= 1, i++)
            {
                uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
                if (i >= maxPresentTables)
                {
                    rows = 0;
                }
                sizes[i] = rows;
                if (i < mdTables.Length)
                {
                    mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
                }
            }

            if (HasExtraData)
            {
                extraData = imageStream.ReadUInt32();
            }

            dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes);

            var currentRva = peImage.ToRVA(imageStream.FileOffset) + (uint)imageStream.Position;

            foreach (var mdTable in mdTables)
            {
                var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
                mdTable.ImageStream = peImage.CreateStream(currentRva, dataLen);
                var newRva = currentRva + (uint)dataLen;
                if (newRva < currentRva)
                {
                    throw new BadImageFormatException("Too big MD table");
                }
                currentRva = newRva;
            }

            InitializeTables();
        }
Ejemplo n.º 10
0
		/// <summary>
		/// Writes a <c>GenericParamConstraint</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawGenericParamConstraintRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				cols[0].Write(writer, row.Owner);
				cols[1].Write(writer, row.Constraint);
			}
		}
Ejemplo n.º 11
0
		/// <summary>
		/// Writes a <c>AssemblyOS</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawAssemblyOSRow> table) {
			foreach (var row in table) {
				writer.Write(row.OSPlatformId);
				writer.Write(row.OSMajorVersion);
				writer.Write(row.OSMinorVersion);
			}
		}
Ejemplo n.º 12
0
		/// <summary>
		/// Writes a <c>ENCMap</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawENCMapRow> table) {
			foreach (var row in table)
				writer.Write(row.Token);
		}
Ejemplo n.º 13
0
		/// <summary>
		/// Writes a <c>FieldRVA</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawFieldRVARow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.RVA);
				cols[1].Write(writer, row.Field);
			}
		}
Ejemplo n.º 14
0
        /// <summary>
        ///     Gets a rid list (eg. field list)
        /// </summary>
        /// <param name="tableSource">Source table, eg. <c>TypeDef</c></param>
        /// <param name="tableSourceRid">Row ID in <paramref name="tableSource" /></param>
        /// <param name="colIndex">Column index in <paramref name="tableSource" />, eg. 4 for <c>TypeDef.FieldList</c></param>
        /// <param name="tableDest">Destination table, eg. <c>Field</c></param>
        /// <returns>A new <see cref="RidList" /> instance</returns>
        private RidList GetRidList(MDTable tableSource, uint tableSourceRid, int colIndex, MDTable tableDest)
        {
            var column = tableSource.TableInfo.Columns[colIndex];
            uint startRid, nextListRid;
            bool hasNext;

#if THREAD_SAFE
            tablesStream.theLock.EnterWriteLock(); try {
#endif
            if (!tablesStream.ReadColumn_NoLock(tableSource, tableSourceRid, column, out startRid))
            {
                return(RidList.Empty);
            }
            hasNext = tablesStream.ReadColumn_NoLock(tableSource, tableSourceRid + 1, column, out nextListRid);
#if THREAD_SAFE
        }

        finally { tablesStream.theLock.ExitWriteLock(); }
#endif
            var lastRid = tableDest.Rows + 1;
            if (startRid == 0 || startRid >= lastRid)
            {
                return(RidList.Empty);
            }
            var endRid = hasNext && nextListRid != 0 ? nextListRid : lastRid;
            if (endRid < startRid)
            {
                endRid = startRid;
            }
            if (endRid > lastRid)
            {
                endRid = lastRid;
            }
            return(new ContiguousRidList(startRid, endRid - startRid));
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Returns the offset (in <see cref="fullStream"/>) of a row
 /// </summary>
 /// <param name="table">Table</param>
 /// <param name="rid">A valid row ID (i.e., &gt;= <c>1</c> and &lt;= number of rows)</param>
 /// <param name="offset">Updated with the offset</param>
 /// <returns><c>true</c> if the row exists, <c>false</c> if the row doesn't exist</returns>
 protected abstract bool GetRowOffset(MDTable table, uint rid, out long offset);
Ejemplo n.º 16
0
 /// <summary>
 /// Reads a column
 /// </summary>
 /// <param name="table">The table</param>
 /// <param name="rid">Row ID</param>
 /// <param name="colIndex">Column index in <paramref name="table"/></param>
 /// <param name="value">Result is put here or 0 if we return <c>false</c></param>
 /// <returns><c>true</c> if we could read the column, <c>false</c> otherwise</returns>
 public bool TryReadColumn(MDTable table, uint rid, int colIndex, out uint value) =>
 TryReadColumn(table, rid, table.TableInfo.Columns[colIndex], out value);
Ejemplo n.º 17
0
 /// <summary>
 /// Finds all rows owned by <paramref name="key"/> in table <paramref name="tableSource"/>
 /// whose index is <paramref name="keyColIndex"/>. Should be called if <paramref name="tableSource"/>
 /// could be unsorted.
 /// </summary>
 /// <param name="tableSource">Table to search</param>
 /// <param name="keyColIndex">Key column index</param>
 /// <param name="key">Key</param>
 /// <returns>A <see cref="RidList"/> instance</returns>
 protected virtual RidList FindAllRowsUnsorted(MDTable tableSource, int keyColIndex, uint key)
 {
     return(FindAllRows(tableSource, keyColIndex, key));
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Binary searches the table for a <c>rid</c> whose key column at index
 /// <paramref name="keyColIndex"/> is equal to <paramref name="key"/>. The
 /// <see cref="tablesStream"/> has acquired its lock so only <c>*_NoLock</c> methods
 /// may be called.
 /// </summary>
 /// <param name="tableSource">Table to search</param>
 /// <param name="keyColIndex">Key column index</param>
 /// <param name="key">Key</param>
 /// <returns>The <c>rid</c> of the found row, or 0 if none found</returns>
 protected abstract uint BinarySearch_NoLock(MDTable tableSource, int keyColIndex, uint key);
Ejemplo n.º 19
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="mdTable">The MD table</param>
 /// <param name="keyColIndex">Index of key column</param>
 public SortedTable(MDTable mdTable, int keyColIndex)
 {
     InitializeKeys(mdTable, keyColIndex);
     Array.Sort(rows);
 }
Ejemplo n.º 20
0
		/// <summary>
		/// Writes a <c>TypeSpec</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawTypeSpecRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table)
				cols[0].Write(writer, row.Signature);
		}
Ejemplo n.º 21
0
		/// <summary>
		/// Writes a <c>AssemblyRefProcessor</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawAssemblyRefProcessorRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.Processor);
				cols[1].Write(writer, row.AssemblyRef);
			}
		}
Ejemplo n.º 22
0
		/// <summary>
		/// Writes a <c>ImplMap</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawImplMapRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.MappingFlags);
				cols[1].Write(writer, row.MemberForwarded);
				cols[2].Write(writer, row.ImportName);
				cols[3].Write(writer, row.ImportScope);
			}
		}
Ejemplo n.º 23
0
		/// <summary>
		/// Writes a <c>File</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawFileRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.Flags);
				cols[1].Write(writer, row.Name);
				cols[2].Write(writer, row.HashValue);
			}
		}
Ejemplo n.º 24
0
		/// <summary>
		/// Writes a <c>ENCLog</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawENCLogRow> table) {
			foreach (var row in table) {
				writer.Write(row.Token);
				writer.Write(row.FuncCode);
			}
		}
Ejemplo n.º 25
0
		/// <summary>
		/// Writes a <c>ManifestResource</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawManifestResourceRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.Offset);
				writer.Write(row.Flags);
				cols[2].Write(writer, row.Name);
				cols[3].Write(writer, row.Implementation);
			}
		}
Ejemplo n.º 26
0
		/// <summary>
		/// Writes a <c>AssemblyProcessor</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawAssemblyProcessorRow> table) {
			foreach (var row in table)
				writer.Write(row.Processor);
		}
Ejemplo n.º 27
0
		/// <summary>
		/// Writes a <c>GenericParam</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawGenericParamRow> table) {
			var cols = table.TableInfo.Columns;
			bool useKindColumn = cols.Count >= 5;
			foreach (var row in table) {
				writer.Write(row.Number);
				writer.Write(row.Flags);
				cols[2].Write(writer, row.Owner);
				cols[3].Write(writer, row.Name);
				if (useKindColumn)
					cols[4].Write(writer, row.Kind);
			}
		}
Ejemplo n.º 28
0
		/// <summary>
		/// Writes a <c>AssemblyRef</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawAssemblyRefRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.MajorVersion);
				writer.Write(row.MinorVersion);
				writer.Write(row.BuildNumber);
				writer.Write(row.RevisionNumber);
				writer.Write(row.Flags);
				cols[5].Write(writer, row.PublicKeyOrToken);
				cols[6].Write(writer, row.Name);
				cols[7].Write(writer, row.Locale);
				cols[8].Write(writer, row.HashValue);
			}
		}
Ejemplo n.º 29
0
 internal bool TryReadColumn24(MDTable table, uint rid, int colIndex, out uint value) =>
 TryReadColumn24(table, rid, table.TableInfo.Columns[colIndex], out value);
Ejemplo n.º 30
0
		/// <summary>
		/// Writes a <c>AssemblyRefOS</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawAssemblyRefOSRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.OSPlatformId);
				writer.Write(row.OSMajorVersion);
				writer.Write(row.OSMinorVersion);
				cols[3].Write(writer, row.AssemblyRef);
			}
		}
Ejemplo n.º 31
0
		/// <summary>
		/// Writes a <c>PropertyMap</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawPropertyMapRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				cols[0].Write(writer, row.Parent);
				cols[1].Write(writer, row.PropertyList);
			}
		}
Ejemplo n.º 32
0
		/// <summary>
		/// Writes a <c>ExportedType</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawExportedTypeRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.Flags);
				writer.Write(row.TypeDefId);
				cols[2].Write(writer, row.TypeName);
				cols[3].Write(writer, row.TypeNamespace);
				cols[4].Write(writer, row.Implementation);
			}
		}
Ejemplo n.º 33
0
		/// <summary>
		/// Writes a <c>PropertyPtr</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawPropertyPtrRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table)
				cols[0].Write(writer, row.Property);
		}
Ejemplo n.º 34
0
		/// <summary>
		/// Writes a <c>NestedClass</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawNestedClassRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				cols[0].Write(writer, row.NestedClass);
				cols[1].Write(writer, row.EnclosingClass);
			}
		}
Ejemplo n.º 35
0
		/// <summary>
		/// Writes a <c>Property</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawPropertyRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.PropFlags);
				cols[1].Write(writer, row.Name);
				cols[2].Write(writer, row.Type);
			}
		}
Ejemplo n.º 36
0
		/// <summary>
		/// Writes a <c>MethodSpec</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawMethodSpecRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				cols[0].Write(writer, row.Method);
				cols[1].Write(writer, row.Instantiation);
			}
		}
Ejemplo n.º 37
0
		/// <summary>
		/// Writes a <c>MethodSemantics</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawMethodSemanticsRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				writer.Write(row.Semantic);
				cols[1].Write(writer, row.Method);
				cols[2].Write(writer, row.Association);
			}
		}
Ejemplo n.º 38
0
		/// <summary>
		/// Writes a <c>MethodImpl</c> table
		/// </summary>
		/// <param name="writer">Writer</param>
		/// <param name="table">Table</param>
		public static void Write(this BinaryWriter writer, MDTable<RawMethodImplRow> table) {
			var cols = table.TableInfo.Columns;
			foreach (var row in table) {
				cols[0].Write(writer, row.Class);
				cols[1].Write(writer, row.MethodBody);
				cols[2].Write(writer, row.MethodDeclaration);
			}
		}
Ejemplo n.º 39
0
        /// <summary>
        /// Initializes MD tables
        /// </summary>
        /// <param name="typeSystemTableRows">Type system table rows (from #Pdb stream)</param>
        public void Initialize(uint[] typeSystemTableRows)
        {
            if (initialized)
            {
                throw new Exception("Initialize() has already been called");
            }
            initialized = true;

            reserved1    = imageStream.ReadUInt32();
            majorVersion = imageStream.ReadByte();
            minorVersion = imageStream.ReadByte();
            flags        = (MDStreamFlags)imageStream.ReadByte();
            log2Rid      = imageStream.ReadByte();
            validMask    = imageStream.ReadUInt64();
            sortedMask   = imageStream.ReadUInt64();

            int maxPresentTables;
            var dnTableSizes = new DotNetTableSizes();
            var tableInfos   = dnTableSizes.CreateTables(majorVersion, minorVersion, out maxPresentTables);

            if (typeSystemTableRows != null)
            {
                maxPresentTables = DotNetTableSizes.normalMaxTables;
            }
            mdTables = new MDTable[tableInfos.Length];

            ulong valid = validMask;
            var   sizes = new uint[64];

            for (int i = 0; i < 64; valid >>= 1, i++)
            {
                uint rows = (valid & 1) == 0 ? 0 : imageStream.ReadUInt32();
                if (i >= maxPresentTables)
                {
                    rows = 0;
                }
                sizes[i] = rows;
                if (i < mdTables.Length)
                {
                    mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]);
                }
            }

            if (HasExtraData)
            {
                extraData = imageStream.ReadUInt32();
            }

            var debugSizes = sizes;

            if (typeSystemTableRows != null)
            {
                debugSizes = new uint[sizes.Length];
                for (int i = 0; i < 64; i++)
                {
                    if (DotNetTableSizes.IsSystemTable((Table)i))
                    {
                        debugSizes[i] = typeSystemTableRows[i];
                    }
                    else
                    {
                        debugSizes[i] = sizes[i];
                    }
                }
            }

            dnTableSizes.InitializeSizes(HasBigStrings, HasBigGUID, HasBigBlob, sizes, debugSizes);

            var currentPos = (FileOffset)imageStream.Position;

            foreach (var mdTable in mdTables)
            {
                var dataLen = (long)mdTable.TableInfo.RowSize * (long)mdTable.Rows;
                mdTable.ImageStream = imageStream.Create(currentPos, dataLen);
                var newPos = currentPos + (uint)dataLen;
                if (newPos < currentPos)
                {
                    throw new BadImageFormatException("Too big MD table");
                }
                currentPos = newPos;
            }

            InitializeTables();
        }