/* * private static UInt32 PadTo4(UInt32 RVA) * { * UInt32 Cleared = RVA & ~0x3U; * return (RVA == Cleared) ? RVA : RVA + 0x4U; * } */ internal void InitMetaData() { if (B == null) { throw new ObjectDisposedException(null); } if (parsedMetaData) { return; } SeekToRVA(MetaDataDDRVA); UInt32 MetaDataRVA = B.ReadUInt32(); UInt32 MetaDataSize = B.ReadUInt32(); if ((MetaDataRVA == 0) || (MetaDataSize == 0)) { throw new BadImageFormatException(); } MetadataRoot = RVAToFileAddress(MetaDataRVA); UInt32 VersionLengthRVA = MetaDataRVA + 12; UInt32 VersionStringRVA = VersionLengthRVA + 4; SeekToRVA(VersionLengthRVA); UInt32 VersionLength = B.ReadUInt32(); String Version = ReadUTF8String(VersionLength); UInt32 FlagsRVA = VersionStringRVA + VersionLength; UInt32 NStreamsRVA = FlagsRVA + 2; SeekToRVA(NStreamsRVA); UInt16 NStreams = B.ReadUInt16(); Streams = new StreamDesc[NStreams]; for (int i = 0; i < NStreams; i++) { Streams[i] = new StreamDesc(B, MetadataRoot); } StreamDesc stringStream, blobStream, TablesStream; if (!FindStream("#~", out TablesStream)) { if (!FindStream("#-", out TablesStream)) { throw new BadImageFormatException(); } } if (!FindStream("#Strings", out stringStream)) { throw new BadImageFormatException(); } if (!FindStream("#Blob", out blobStream)) { throw new BadImageFormatException(); } TablesStream.SeekTo(B, 0); metaData = new MDTables(B, stringStream, blobStream); // metaData.DumpStringHeap(); parsedMetaData = true; }
internal MDTables(BinaryReader reader, StreamDesc stringSD, StreamDesc blobSD) { // Positioned at start of #~ stream stringStream = stringSD; blobStream = blobSD; B = reader; B.BaseStream.Seek(4, SeekOrigin.Current); // Skip reserved byte Major = B.ReadByte(); byte Minor = B.ReadByte(); // Console.WriteLine("Table schema version {0}.{1}", Major, Minor); byte HeapSizes = B.ReadByte(); stringIndex = ((HeapSizes & 0x01) == 0) ? 2U : 4U; GUIDIndex = ((HeapSizes & 0x02) == 0) ? 2U : 4U; blobIndex = ((HeapSizes & 0x04) == 0) ? 2U : 4U; B.ReadByte(); // Reserved UInt64 Valid = B.ReadUInt64(); UInt64 Sorted = B.ReadUInt64(); NRows = new UInt32[(Int32)Tables.MaxTable + 1]; int NTables = 0; UInt64 VBit = 1UL; for (int Table = 0; Table <= (int)Tables.MaxTable; Table++, VBit <<= 1) { if ((Valid & VBit) != 0) { NRows[Table] = B.ReadUInt32(); if (NRows[Table] == 0) { //Console.WriteLine("Table {0} is valid with 0 rows", Table); } // Console.WriteLine("Table {0} ({1}) has {2} rows", Names[Table], Table, NRows[Table]); NTables += 1; } } // Console.WriteLine("Found {0} tables", NTables); ComputeRowLengths(); /* * for (int i = 0; i <= (int) Tables.MaxTable; i++) * Console.WriteLine("Table {0} ({1}) has {2} bytes per row", * Names[i], i, lengths[i]); */ tableAt = new UInt32[(Int32)Tables.MaxTable + 1]; VBit = 1UL; UInt32 Offset = (UInt32)B.BaseStream.Position; for (int Table = 0; Table <= (int)Tables.MaxTable; Table++, VBit <<= 1) { tableAt[Table] = Offset; // Console.WriteLine("Table {2} ({0}) at offset 0x{1:x}", Table, Offset, Names[(UInt32)Table]); Offset += lengths[Table] * NRows[Table]; if (((Valid & VBit) != 0) && (NRows[Table] != 0) && (lengths[Table] == 0)) { throw new BadImageFormatException(String.Format(CultureInfo.CurrentCulture, Res.UnknownMetadataTable, Table)); } } }
private bool FindStream(String name, out StreamDesc result) { foreach (StreamDesc s in Streams) { if (s.Name.Equals(name)) { result = s; return(true); } } result = null; return(false); }
internal MDTables(BinaryReader reader, StreamDesc stringSD, StreamDesc blobSD) { // Positioned at start of #~ stream stringStream = stringSD; blobStream = blobSD; B = reader; B.BaseStream.Seek(4, SeekOrigin.Current); // Skip reserved byte Major = B.ReadByte(); byte Minor = B.ReadByte(); // Console.WriteLine("Table schema version {0}.{1}", Major, Minor); byte HeapSizes = B.ReadByte(); stringIndex = ((HeapSizes & 0x01) == 0) ? 2U : 4U; GUIDIndex = ((HeapSizes & 0x02) == 0) ? 2U : 4U; blobIndex = ((HeapSizes & 0x04) == 0) ? 2U : 4U; B.ReadByte(); // Reserved UInt64 Valid = B.ReadUInt64(); UInt64 Sorted = B.ReadUInt64(); NRows = new UInt32[(Int32)Tables.MaxTable + 1]; int NTables = 0; UInt64 VBit = 1UL; for (int Table = 0; Table <= (int)Tables.MaxTable; Table++, VBit <<= 1) { if ((Valid & VBit) != 0) { NRows[Table] = B.ReadUInt32(); if (NRows[Table] == 0) { //Console.WriteLine("Table {0} is valid with 0 rows", Table); } // Console.WriteLine("Table {0} ({1}) has {2} rows", Names[Table], Table, NRows[Table]); NTables += 1; } } // Console.WriteLine("Found {0} tables", NTables); ComputeRowLengths(); /* for (int i = 0; i <= (int) Tables.MaxTable; i++) Console.WriteLine("Table {0} ({1}) has {2} bytes per row", Names[i], i, lengths[i]); */ tableAt = new UInt32[(Int32)Tables.MaxTable + 1]; VBit = 1UL; UInt32 Offset = (UInt32)B.BaseStream.Position; for (int Table = 0; Table <= (int)Tables.MaxTable; Table++, VBit <<= 1) { tableAt[Table] = Offset; // Console.WriteLine("Table {2} ({0}) at offset 0x{1:x}", Table, Offset, Names[(UInt32)Table]); Offset += lengths[Table] * NRows[Table]; if (((Valid & VBit) != 0) && (NRows[Table] != 0) && (lengths[Table] == 0)) throw new BadImageFormatException(String.Format(CultureInfo.CurrentCulture, Res.UnknownMetadataTable, Table)); } }
/* private static UInt32 PadTo4(UInt32 RVA) { UInt32 Cleared = RVA & ~0x3U; return (RVA == Cleared) ? RVA : RVA + 0x4U; } */ internal void InitMetaData() { if (B == null) throw new ObjectDisposedException(null); if (parsedMetaData) return; SeekToRVA(MetaDataDDRVA); UInt32 MetaDataRVA = B.ReadUInt32(); UInt32 MetaDataSize = B.ReadUInt32(); if ((MetaDataRVA == 0) || (MetaDataSize == 0)) throw new BadImageFormatException(); MetadataRoot = RVAToFileAddress(MetaDataRVA); UInt32 VersionLengthRVA = MetaDataRVA + 12; UInt32 VersionStringRVA = VersionLengthRVA + 4; SeekToRVA(VersionLengthRVA); UInt32 VersionLength = B.ReadUInt32(); String Version = ReadUTF8String(VersionLength); UInt32 FlagsRVA = VersionStringRVA + VersionLength; UInt32 NStreamsRVA = FlagsRVA + 2; SeekToRVA(NStreamsRVA); UInt16 NStreams = B.ReadUInt16(); Streams = new StreamDesc[NStreams]; for (int i = 0; i < NStreams; i++) Streams[i] = new StreamDesc(B, MetadataRoot); StreamDesc stringStream, blobStream, TablesStream; if (!FindStream("#~", out TablesStream)) if (!FindStream("#-", out TablesStream)) throw new BadImageFormatException(); if (!FindStream("#Strings", out stringStream)) throw new BadImageFormatException(); if (!FindStream("#Blob", out blobStream)) throw new BadImageFormatException(); TablesStream.SeekTo(B, 0); metaData = new MDTables(B, stringStream, blobStream); // metaData.DumpStringHeap(); parsedMetaData = true; }
private bool FindStream(String name, out StreamDesc result) { foreach (StreamDesc s in Streams) { if (s.Name.Equals(name)) { result = s; return true; } } result = null; return false; }