/// <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(); }
/// <summary> /// Calculates the length. This will set all MD tables to read-only. /// </summary> public void CalculateLength() { if (length != 0) return; SetReadOnly(); majorVersion = options.MajorVersion ?? 2; minorVersion = options.MinorVersion ?? 0; if (((majorVersion << 8) | minorVersion) <= 0x100) { if (!GenericParamTable.IsEmpty || !MethodSpecTable.IsEmpty || !GenericParamConstraintTable.IsEmpty) throw new ModuleWriterException("Tables heap version <= v1.0 but generic tables are not empty"); } var dnTableSizes = new DotNetTableSizes(); var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion); dnTableSizes.InitializeSizes(bigStrings, bigGuid, bigBlob, GetRowCounts()); for (int i = 0; i < Tables.Length; i++) Tables[i].TableInfo = tableInfos[i]; length = 24; foreach (var mdt in Tables) { if (mdt.IsEmpty) continue; length += (uint)(4 + mdt.TableInfo.RowSize * mdt.Rows); } if (options.ExtraData.HasValue) length += 4; }
/// <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(); }