private void BuildMetaDataStreams(BinaryReader fileReader) { // this code is factored out of script for ease of script reading this.metaDataStreams = new MetaDataStream[this.metaDataRoot.NumberOfStreams]; // lets initialise some handy variables to save typing long rootPos = this.metaDataRoot.StartOfRoot; for (int i = 0; i < this.metaDataRoot.NumberOfStreams; i++) { // handy variable for shorter code MetaDataStreamHeader streamHead = this.metaDataRoot.MetaDataStreamHeaders[i]; // move to correct position for start of stream. This is listed // as an offset from the start of the metadataroot. fileReader.BaseStream.Position = rootPos + streamHead.Offset; this.metaDataStreams[i] = new MetaDataStream(fileReader, streamHead.Name, streamHead.Size, this); if (this.metaDataStreams[i].Name == "#~") { this.tablesStream = this.metaDataStreams[i]; } if (this.metaDataStreams[i].Name == "#Strings") { this.stringHeap = this.metaDataStreams[i]; } } }
public readonly uint[] NumberOfRows; // array of 4 byte unsigned ints indicating num of rows for each present table public TablesHeader(BinaryReader reader, MetaDataStream stringheap) { //this.strings = new ArrayList(); //this.stringHeap = stringheap; //this.reader = reader; this.NumberOfRows = new UInt32[64]; // skip the first 6 bytes as we are not interested in them. They represent the fixed // values of 0,1,0 for reserved, major version and minor version. reader.BaseStream.Position += 6; this.HeapSizes = reader.ReadByte(); // another fixed value we are not interested in reader.BaseStream.Position += 1; this.Valid = reader.ReadUInt64(); this.Sorted = reader.ReadUInt64(); uint length = 0; // we are now ready to start reading the row lengths for (int i = 0; i < 64; i++) { length = 0; if (((this.Valid >> i) & 1) == 1) { length = reader.ReadUInt32(); } this.NumberOfRows[i] = length; } }
public MetaDataTable(Tables.TableName table, Tables parent) //long startPosition, TablesHeader tablesHeader, MetaDataStream stringHeap, BinaryReader reader, Hashtable indexes) { this.tableNumber = (int)table; this.parent = parent; this.startPosition = parent.reader.BaseStream.Position; this.reader = this.parent.reader; this.indexSizeIndicator = this.parent.tablesHeader.HeapSizes; this.stringHeap = this.parent.stringHeap; this.numberOfRows = this.parent.RowsPerTable[this.tableNumber]; this.ReadRows(); }
//Retrieves a string from the StringHeap public string GetStringFromStringHeap(uint stringIndex) { MetaDataStream stringHeapStream = this.peFile.stringHeap; StringBuilder retrievedStringBuilder = new StringBuilder(); stringHeapStream.Reader.BaseStream.Position = stringHeapStream.StartPositionInFile + stringIndex; byte nextChar = stringHeapStream.Reader.ReadByte(); while (nextChar != 0) { retrievedStringBuilder.Append((char)nextChar); nextChar = stringHeapStream.Reader.ReadByte(); } return(retrievedStringBuilder.ToString()); }
public Tables(TablesHeader tablesHeader, MetaDataStream stringHeap, BinaryReader reader) { this.tablesHeader = tablesHeader; this.stringHeap = stringHeap; this.reader = reader; this.indexSizeIndicator = tablesHeader.HeapSizes; this.RowsPerTable = tablesHeader.NumberOfRows; // set up a table of coded index information // the first figure in the array is the number of bits needed to encode // which table the index is pointing to. Note, some indexes use more bits // than are necessary, for example CustomAttributeType uses 3 bits even though // it only points to 2 tables, so in theory could be encoded in 1 bit. this.CodedIndexInformation = new object[12]; CodedIndexInformation[(int)Tables.CodedIndexType.TypeDefOrRef] = new int[] { 2, (int)Tables.TableName.TypeDef, (int)Tables.TableName.TypeRef, (int)Tables.TableName.TypeSpec }; CodedIndexInformation[(int)Tables.CodedIndexType.HasConstant] = new int[] { 2, (int)Tables.TableName.Field, (int)Tables.TableName.Param, (int)Tables.TableName.Property }; CodedIndexInformation[(int)Tables.CodedIndexType.HasCustomAttribute] = new int[] { 5, (int)Tables.TableName.MethodDef, (int)Tables.TableName.Field, (int)Tables.TableName.TypeRef, (int)Tables.TableName.TypeDef, (int)Tables.TableName.Param, (int)Tables.TableName.InterfaceImpl, (int)Tables.TableName.MemberRef, (int)Tables.TableName.Module, (int)Tables.TableName.DeclSecurity, (int)Tables.TableName.Property, (int)Tables.TableName.EventX, (int)Tables.TableName.StandAloneSig, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.TypeSpec, (int)Tables.TableName.Assembly, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.File, (int)Tables.TableName.ExportedType, (int)Tables.TableName.ManifestResource }; CodedIndexInformation[(int)Tables.CodedIndexType.HasFieldMarshal] = new int[] { 1, (int)Tables.TableName.Field, (int)Tables.TableName.Param }; CodedIndexInformation[(int)Tables.CodedIndexType.HasDeclSecurity] = new int[] { 2, (int)Tables.TableName.TypeDef, (int)Tables.TableName.MethodDef, (int)Tables.TableName.Assembly }; CodedIndexInformation[(int)Tables.CodedIndexType.MemberRefParent] = new int[] { 3, (int)Tables.TableName.TypeRef, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.MethodDef, (int)Tables.TableName.TypeSpec }; CodedIndexInformation[(int)Tables.CodedIndexType.HasSemantics] = new int[] { 1, (int)Tables.TableName.EventX, (int)Tables.TableName.Property }; CodedIndexInformation[(int)Tables.CodedIndexType.MethodDefOrRef] = new int[] { 1, (int)Tables.TableName.MethodDef, (int)Tables.TableName.MemberRef }; CodedIndexInformation[(int)Tables.CodedIndexType.MemberForwarded] = new int[] { 1, (int)Tables.TableName.Field, (int)Tables.TableName.MethodDef }; CodedIndexInformation[(int)Tables.CodedIndexType.Implementation] = new int[] { 2, (int)Tables.TableName.File, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.ExportedType }; CodedIndexInformation[(int)Tables.CodedIndexType.CustomAttributeType] = new int[] { 3, (int)Tables.TableName.MethodDef, (int)Tables.TableName.MemberRef }; CodedIndexInformation[(int)Tables.CodedIndexType.ResolutionScope] = new int[] { 2, (int)Tables.TableName.Module, (int)Tables.TableName.ModuleRef, (int)Tables.TableName.AssemblyRef, (int)Tables.TableName.TypeRef }; this.Module = new Module(Tables.TableName.Module, this); this.TypeRef = new TypeRef(Tables.TableName.TypeRef, this); this.TypeDef = new TypeDef(Tables.TableName.TypeDef, this); this.Field = new Field(Tables.TableName.Field, this); this.MethodDef = new MethodDef(Tables.TableName.MethodDef, this); this.Param = new Param(Tables.TableName.Param, this); this.InterfaceImpl = new InterfaceImpl(Tables.TableName.InterfaceImpl, this); this.MemberRef = new MemberRef(Tables.TableName.MemberRef, this); this.Constant = new Constant(Tables.TableName.Constant, this); this.CustomAttribute = new CustomAttribute(Tables.TableName.CustomAttribute, this); this.FieldMarshal = new FieldMarshal(Tables.TableName.FieldMarshal, this); this.DeclSecurity = new DeclSecurity(Tables.TableName.DeclSecurity, this); this.ClassLayout = new ClassLayout(Tables.TableName.ClassLayout, this); this.FieldLayout = new FieldLayout(Tables.TableName.FieldLayout, this); this.StandAloneSig = new StandAloneSig(Tables.TableName.StandAloneSig, this); this.EventMap = new EventMap(Tables.TableName.EventMap, this); this.EventX = new EventX(Tables.TableName.EventX, this); this.PropertyMap = new PropertyMap(Tables.TableName.PropertyMap, this); this.Property = new Property(Tables.TableName.Property, this); this.MethodSemantics = new MethodSemantics(Tables.TableName.MethodSemantics, this); this.MethodImpl = new MethodImpl(Tables.TableName.MethodImpl, this); this.ModuleRef = new ModuleRef(Tables.TableName.ModuleRef, this); this.TypeSpec = new TypeSpec(Tables.TableName.TypeSpec, this); this.ImplMap = new ImplMap(Tables.TableName.ImplMap, this); }