MDStreamFlags GetMDStreamFlags() { MDStreamFlags flags = 0; if (bigStrings) { flags |= MDStreamFlags.BigStrings; } if (bigGuid) { flags |= MDStreamFlags.BigGUID; } if (bigBlob) { flags |= MDStreamFlags.BigBlob; } if (options.ExtraData.HasValue) { flags |= MDStreamFlags.ExtraData; } if (hasDeletedRows) { flags |= MDStreamFlags.HasDelete; } return(flags); }
/// <summary> /// Initializes MD tables /// </summary> /// <param name="peImage">The PEImage</param> public void Initialize(IPEImage peImage) { 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(); }
public TablesHeapWriter(TablesMDHeap tablesHeap, StringsMDHeap stringsHeap, GuidMDHeap guidHeap, BlobMDHeap blobHeap) { this.tablesHeap = tablesHeap; this.stringsHeap = stringsHeap; this.guidHeap = guidHeap; this.blobHeap = blobHeap; if (stringsHeap.IsBig) { mdStreamFlags |= MDStreamFlags.BigStrings; } if (guidHeap.IsBig) { mdStreamFlags |= MDStreamFlags.BigGUID; } if (blobHeap.IsBig) { mdStreamFlags |= MDStreamFlags.BigBlob; } }
void Initialize() { if (initialized) { return; } initialized = true; var buffer = Span.Buffer; var pos = Span.Span.Start; reserved1 = buffer.ReadUInt32(pos); majorVersion = buffer.ReadByte(pos + 4); minorVersion = buffer.ReadByte(pos + 5); flags = (MDStreamFlags)buffer.ReadByte(pos + 6); log2Rid = buffer.ReadByte(pos + 7); validMask = buffer.ReadUInt64(pos + 8); sortedMask = buffer.ReadUInt64(pos + 0x10); pos += 0x18; Debug.Assert(Span.Span.Start + MinimumSize == pos); Debug.Assert(Span.Span.Contains(pos - 1), "Creator should've verified this"); var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion, out int maxPresentTables); var rowsCount = new uint[tableInfos.Length]; ulong valid = validMask; var sizes = new uint[64]; int rowsFieldCount = 0; for (int i = 0; i < 64; valid >>= 1, i++) { uint rows; if ((valid & 1) == 0 || !Span.Span.Contains(pos + 3)) { rows = 0; } else { rowsFieldCount++; rows = buffer.ReadUInt32(pos); pos += 4; } if (i >= maxPresentTables) { rows = 0; } // Mono ignores the high byte rows &= 0x00FFFFFF; sizes[i] = rows; if (i < rowsCount.Length) { rowsCount[i] = rows; } } bool hasExtraData = false; if ((flags & MDStreamFlags.ExtraData) != 0 && Span.Span.Contains(pos + 3)) { hasExtraData = true; extraData = buffer.ReadUInt32(pos); pos += 4; } headerSpan = HexSpan.FromBounds(Span.Span.Start, pos); dnTableSizes.InitializeSizes((flags & MDStreamFlags.BigStrings) != 0, (flags & MDStreamFlags.BigGUID) != 0, (flags & MDStreamFlags.BigBlob) != 0, sizes); mdTables = new MDTable[tableInfos.Length]; mdTablesReadOnly = new ReadOnlyCollection <MDTable>(mdTables); tableRecordDataFactories = new TableRecordDataFactory[tableInfos.Length]; var tablesStartPos = pos; bool bad = !Span.Span.Contains(pos); for (int i = 0; i < rowsCount.Length; i++) { var rows = rowsCount[i]; var mdTable = new MDTable(pos, (Table)i, rows, tableInfos[i]); if (bad || mdTable.Span.End > Span.End.Position) { mdTable = new MDTable(pos, (Table)i, 0, tableInfos[i]); bad = true; } pos = mdTable.Span.End; mdTables[i] = mdTable; tableRecordDataFactories[i] = CreateFactory(mdTable); } tablesSpan = HexSpan.FromBounds(HexPosition.Min(Span.End.Position, tablesStartPos), HexPosition.Min(Span.End.Position, pos)); tablesHeaderData = new TablesHeaderDataImpl(new HexBufferSpan(buffer, headerSpan), hasExtraData, rowsFieldCount); }
/// <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(); }
/// <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(); }