// // Copyright (c) Microsoft Corporation. All rights reserved. // // Loader of MetaData information namespace Bartok.MSIL { using System; using System.Collections; using System.IO; using System.Reflection; using System.Text; using Bartok.DebugInfo; internal class MetaDataLoader { // Constructor Methods internal static MetaData getMetaData(String name, PELoader peLoader, bool fLoadCode, bool fLoadDebugInfo) { int metaDataOffset = peLoader.getMetaDataOffset(); Stream fileStream = peLoader.getStream(); fileStream.Seek(metaDataOffset, SeekOrigin.Begin); BinaryReader reader = new BinaryReader(fileStream); StorageSignature storageSignature = new StorageSignature(reader); StorageHeader storageHeader = new StorageHeader(reader); // The pointer is at the first stream in the list MetaDataFormat format = MetaDataFormat.Invalid; // Lightning/Src/MD/Runtime/MDInternalDisp.cpp StorageStream dataStream = null; StorageStream stringPoolStream = null; StorageStream blobPoolStream = null; StorageStream userBlobPoolStream = null; StorageStream guidPoolStream = null; MetaDataLoader mdLoader; for (int i = 0; i < storageHeader.streamCount; i++) { StorageStream storageStream = new StorageStream(reader); switch (storageStream.name) { case StorageStream.COMPRESSED_MODEL: if (format == MetaDataFormat.Invalid || format == MetaDataFormat.ICR) { format = MetaDataFormat.ReadOnly; dataStream = storageStream; } break; case StorageStream.ENC_MODEL: if (format == MetaDataFormat.Invalid || format == MetaDataFormat.ICR) { format = MetaDataFormat.ReadWrite; dataStream = storageStream; } break; case StorageStream.SCHEMA: if (format == MetaDataFormat.Invalid) { format = MetaDataFormat.ICR; dataStream = storageStream; } break; case StorageStream.STRING_POOL: stringPoolStream = storageStream; break; case StorageStream.BLOB_POOL: blobPoolStream = storageStream; break; case StorageStream.USER_BLOB_POOL: userBlobPoolStream = storageStream; break; case StorageStream.VARIANT_POOL: // It doesn't look like we are using this stream, ever break; case StorageStream.GUID_POOL: guidPoolStream = storageStream; break; default: throw new IllegalMetaDataFormatException("Unknown stream name "+storageStream.name); } } switch (format) { case MetaDataFormat.Invalid: throw new IllegalMetaDataFormatException("No valid metadata format found"); case MetaDataFormat.ReadOnly: mdLoader = new MetaDataLoader(peLoader, fileStream, metaDataOffset, dataStream, stringPoolStream, blobPoolStream, userBlobPoolStream, guidPoolStream); break; case MetaDataFormat.ReadWrite: throw new IllegalMetaDataFormatException("MetaDataReadWrite format on disk"); case MetaDataFormat.ICR: throw new IllegalMetaDataFormatException("Cannot handle ICR metadata format"); default: throw new IllegalMetaDataFormatException("Unknown format "+format); } int methodIndex = 1; bool dllHasDebugInfo = false; try { if (fLoadDebugInfo && fLoadCode) { if (PDBLoader.OpenPdbFile(name) == 0) { dllHasDebugInfo = true; mdLoader.LoadDebugSymbolInfo(); } } foreach (MetaDataMethod method in mdLoader.methodArray) { if (fLoadCode) { bool methodHasDebugInfo = false; int baseLineNumber = 0; int lastLineNumber = 0; int numOfLines = 0; String srcFileName = null; if (fLoadDebugInfo && dllHasDebugInfo) { // load line number information from the dll. int token = ((int)MetaDataTableIndices.Method <<24) | methodIndex; long count; // line number count uint length; // src file name length PDBLoader.GetLineNumberCount(token, out count, out length); if (count > 0) { // there is line number infor. for this method int[] lines = new int[count]; int[] offsets = new int[count]; int[] columns = new int[count]; StringBuilder fileName = new StringBuilder((int)length); int lineCount = PDBLoader.LoadLineNumber(token, lines, columns, offsets, fileName); if (lineCount != count) Console.WriteLine("Error! Reading line number" + lineCount + " " + count); int baseOffset = offsets[0]; for (int i = 0; i < lineCount; i++) { if (lines[i] == 0xFEEFEE) { // Mask noise from the dll files if (i > 0) { lines[i] = lines[i-1]; columns[i] = columns[i-1]; } else if (i < (lineCount - 1)) { lines[i] = lines[i+1] - 1; columns[i] = 0; } else { Console.WriteLine("Error! No Valid lineNumber"); lines[i] = 1; columns[i] = 0; } } // adjust offset to be 0 based. offsets[i] -= baseOffset; } // load instructions srcFileName = fileName.ToString(); method.loadInstructions(mdLoader, peLoader, fileStream, lines, columns, offsets, srcFileName, lineCount); baseLineNumber = lines[0] - 1; lastLineNumber = lines[lineCount-1] + 1; numOfLines = lineCount; methodHasDebugInfo = true; } else { method.loadInstructions(mdLoader, peLoader, fileStream, null, null, null, null, 0); } } else { method.loadInstructions(mdLoader, peLoader, fileStream, null, null, null, null, 0); } method.BaseLineNumber = new CVLineNumber(baseLineNumber, 0, srcFileName); method.LastLineNumber = new CVLineNumber(lastLineNumber, 0, srcFileName); method.NumOfLines = numOfLines; method.SrcFileName = srcFileName; method.HasDebugInfo = methodHasDebugInfo; } if (method.Rva == 0) { method.IsEmpty = true; } methodIndex++; } } finally { if (dllHasDebugInfo) { PDBLoader.ClosePdbFile(); } } int entryPointToken = peLoader.getEntryPoint(); MetaDataMethod entryPoint = (entryPointToken == 0) ? null : (MetaDataMethod) mdLoader.getObjectFromToken(entryPointToken); int imageBase = peLoader.getImageBase(); return new MetaData(name, entryPoint, imageBase, mdLoader.moduleArray, mdLoader.typeRefArray, mdLoader.typeDefArray, mdLoader.fieldPtrArray, mdLoader.fieldArray, mdLoader.methodPtrArray, mdLoader.methodArray, mdLoader.paramPtrArray, mdLoader.paramArray, mdLoader.interfaceImplArray, mdLoader.memberRefArray, mdLoader.constantArray, mdLoader.customAttributeArray, mdLoader.fieldMarshalArray, mdLoader.declSecurityArray, mdLoader.classLayoutArray, mdLoader.fieldLayoutArray, mdLoader.standAloneSigArray, mdLoader.eventMapArray, mdLoader.eventPtrArray, mdLoader.eventArray, mdLoader.propertyMapArray, mdLoader.propertyPtrArray, mdLoader.propertyArray, mdLoader.methodSemanticsArray, mdLoader.methodImplArray, mdLoader.moduleRefArray, mdLoader.typeSpecArray, mdLoader.implMapArray, mdLoader.fieldRVAArray, mdLoader.assemblyArray, mdLoader.assemblyProcessorArray, mdLoader.assemblyOSArray, mdLoader.assemblyRefArray, mdLoader.assemblyRefProcessorArray, mdLoader.assemblyRefOSArray, mdLoader.fileArray, mdLoader.exportedTypeArray, mdLoader.manifestResourceArray, mdLoader.nestedClassArray, mdLoader.relocationArray, mdLoader.vtableFixupArray, mdLoader.delayImportTable); } private void LoadDebugSymbolInfo() { // read in local var info int varCount; int nameLength; int methodCount = PDBLoader.GetMethodCount(out varCount, out nameLength); int[] slots = new int[varCount]; String[] varNames = new String[varCount]; StringBuilder varName = new StringBuilder(nameLength); int slot; int methodToken; int symTable = PDBLoader.OpenSymbolTable(); while (symTable != -1) { int symTag = PDBLoader.GetNextVar(out slot, out methodToken, varName); int count = 0; int lastMethod = -1; int maxslot = 0; // somehow certain locals are not in the // sym table, however, they have slots, // therefore slot number can be bigger than // sym count while (symTag != (int)SymTag.SymTagEnd) { if (symTag == (int) SymTag.SymTagFunction) { if (lastMethod != -1) { // finish last method int numOfLocals = maxslot + 1; if (numOfLocals < count) { numOfLocals = count; } UpdateMethodDebugVarInfo(lastMethod, count, slots, numOfLocals, varNames); lastMethod = -1; } // start current method count = 0; maxslot = 0; lastMethod = methodToken; } else if (symTag == (int)SymTag.SymTagLocal) { slots[count] = slot; if (slot > maxslot) { maxslot = slot; } varNames[count] = varName.ToString(); count++; } else { Console.WriteLine("wrong sym tag"); } symTag = PDBLoader.GetNextVar(out slot, out methodToken, varName); } if (lastMethod != -1) { int numOfLocals = maxslot + 1; if (numOfLocals < count) { numOfLocals = count; } UpdateMethodDebugVarInfo(lastMethod, count, slots, numOfLocals, varNames); lastMethod = -1; } symTable = PDBLoader.NextSymbolTable(); } PDBLoader.CloseSymbolTable(); } private void UpdateMethodDebugVarInfo(int token, int count, int[] slots, int numOfLocals, String[] names) { MetaDataMethod method = (MetaDataMethod) this.getObjectFromToken(token); String[] varNames = new String[numOfLocals]; for (int i = 0; i < count; i++) { varNames[slots[i]] = names[i]; } method.LocalVarNames = varNames; } private static void LoadDebugLineNumberInfo() { } private MetaDataLoader(PELoader peLoader, Stream fileStream, int metaDataOffset, StorageStream dataStream, StorageStream stringPoolStream, StorageStream blobPoolStream, StorageStream userBlobPoolStream, StorageStream guidPoolStream) { this.peLoader = peLoader; this.fileStream = fileStream; this.metaDataOffset = metaDataOffset; this.dataStream = dataStream; this.stringPoolStream = stringPoolStream; this.blobPoolStream = blobPoolStream; this.userBlobPoolStream = userBlobPoolStream; this.guidPoolStream = guidPoolStream; // Read the stream of GUIDs int guidCount = guidPoolStream.size / 16; fileStream.Seek(metaDataOffset + guidPoolStream.offset, SeekOrigin.Begin); this.guidArray = new Guid[guidCount]; byte[] guidBuffer = new byte[16]; for (int i = 0; i < guidCount; i++) { fileStream.Read(guidBuffer, 0, 16); guidArray[i] = new Guid(guidBuffer); } // Read the stream of strings // Ensure that last byte is always zero if (stringPoolStream != null && stringPoolStream.size > 0) { this.stringStreamBuffer = new byte[stringPoolStream.size+1]; fileStream.Seek(metaDataOffset + stringPoolStream.offset, SeekOrigin.Begin); int stringByteCount = fileStream.Read(this.stringStreamBuffer, 0, stringPoolStream.size); if (stringByteCount != stringPoolStream.size) { throw new IllegalMetaDataFormatException("Didn't get all the string bytes"); } } // Read the stream of blobs if (blobPoolStream != null && blobPoolStream.size > 0) { this.blobStreamBuffer = new byte[blobPoolStream.size]; fileStream.Seek(metaDataOffset + blobPoolStream.offset, SeekOrigin.Begin); int blobByteCount = fileStream.Read(this.blobStreamBuffer, 0, blobPoolStream.size); if (blobByteCount != blobPoolStream.size) { throw new IllegalMetaDataFormatException("Didn't get all the blob bytes"); } } // Read the stream of user strings, if there is one if (userBlobPoolStream != null && userBlobPoolStream.size > 0) { this.userStringStreamBuffer = new byte[userBlobPoolStream.size]; fileStream.Seek(metaDataOffset + userBlobPoolStream.offset, SeekOrigin.Begin); int userStringByteCount = fileStream.Read(this.userStringStreamBuffer, 0, userBlobPoolStream.size); if (userStringByteCount != userBlobPoolStream.size) { throw new IllegalMetaDataFormatException("Didn't get all the user string bytes"); } } // Read the resource data, if there is any int resourceOffset = peLoader.getResourceOffset(); int resourceSize = peLoader.getResourceSize(); if (resourceOffset > 0 && resourceSize > 0) { this.resourceBuffer = new byte[resourceSize]; fileStream.Seek(resourceOffset, SeekOrigin.Begin); int resourceCount = fileStream.Read(this.resourceBuffer, 0, resourceSize); if (resourceCount != resourceSize) { throw new IllegalMetaDataFormatException("Didn't get all the resource bytes"); } } // Read the schema fileStream.Seek(metaDataOffset + dataStream.offset, SeekOrigin.Begin); BinaryReader reader = new BinaryReader(fileStream); // First read the fixed fields (CMiniMdSchemaBase) this.ReadSchemaBase(reader); int readBytes = 24; // sizeof(CMiniMDSchemaBase) // Read the variable fields (this is the compressed part) int count = (int) MetaDataTableIndices.Count; long mask = this.maskValid; for (int dst = 0; dst < count; dst++) { if ((mask & 1) != 0) { this.countArray[dst] = reader.ReadInt32(); readBytes += 4; } mask >>= 1; } // Skip the counters we don't understand for (int dst = count; dst < 64; dst++) { if ((mask & 1) != 0) { reader.ReadInt32(); readBytes += 4; } } // Retrieve any extra data if ((this.heapBits & HEAPBITS_MASK_EXTRA_DATA) != 0) { this.extraData = reader.ReadInt32(); readBytes += 4; } if (this.majorVersion != METAMODEL_MAJOR_VER || (this.minorVersion != METAMODEL_MINOR_VER_A && this.minorVersion != METAMODEL_MINOR_VER_B)) { throw new IllegalMetaDataFormatException("Unknown version "+this.majorVersion+"."+this.minorVersion); } if (this.countArray[(int) MetaDataTableIndices.MethodPtr] != 0 || this.countArray[(int) MetaDataTableIndices.FieldPtr] != 0) { throw new IllegalMetaDataFormatException("Trying to open R/W format at R/O"); } // Read the data into the tables int tableSize = this.InitializeRowInfo(); if (readBytes + tableSize > dataStream.size) { throw new IllegalMetaDataFormatException("Table bigger than metadata stream"); } this.InitializeMetaDataTables(reader); } // Helper Methods private void ReadSchemaBase(BinaryReader reader) { this.reserved = reader.ReadInt32(); // Must be zero this.majorVersion = reader.ReadByte(); // Version numbers this.minorVersion = reader.ReadByte(); this.heapBits = reader.ReadByte(); // Bits for heap sizes this.rowId = reader.ReadByte(); // log-base-2 of largest rid this.maskValid = reader.ReadInt64(); // Present table counts this.maskSorted = reader.ReadInt64(); // Sorted tables if (this.reserved != 0) { throw new IllegalMetaDataFormatException("Reserved not zero"); } } private int InitializeRowInfo() { if ((this.heapBits & HEAPBITS_MASK_STRINGS) != 0) { this.stringIndexSize = 4; } else { this.stringIndexSize = 2; } if ((this.heapBits & HEAPBITS_MASK_GUID) != 0) { this.guidIndexSize = 4; } else { this.guidIndexSize = 2; } if ((this.heapBits & HEAPBITS_MASK_BLOB) != 0) { this.blobIndexSize = 4; } else { this.blobIndexSize = 2; } int tableSize = 0; for (int tableIndex = 0; tableIndex < (int) MetaDataTableIndices.Count; tableIndex++) { byte[] columnKinds = TableColumnKinds[tableIndex]; int columnCount = columnKinds.Length; byte[] columnSizes = new byte[columnCount]; byte[] columnOffsets = new byte[columnCount]; this.tableColumnSizes[tableIndex] = columnSizes; this.tableColumnOffsets[tableIndex] = columnOffsets; byte columnOffset = 0; // Running size of record for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) { byte columnKind = columnKinds[columnIndex]; byte columnSize; if (columnKind <= (byte) ColumnKindId.RowIdMax) { if (this.countArray[columnKind] > 0xffff) { columnSize = 4; } else { columnSize = 2; } } else if (columnKind <= (byte) ColumnKindId.CodedTokenMax) { byte codeToken = (byte) (columnKind - (byte) ColumnKindId.CodedToken); TokenType[] tokenTypeList = CodeTokenTypeLists[codeToken]; int maxCount = 0; int listLength = tokenTypeList.Length; for (int i = 0; i < listLength; i++) { TokenType tokenType = tokenTypeList[i]; // Ignore string tokens if (tokenType != TokenType.String) { int index = ((int) tokenType >> 24); if (this.countArray[index] > maxCount) { maxCount = this.countArray[index]; } } } int maxIndex = maxCount << BitsForCountArray[listLength]; if (maxIndex > 0xffff) { columnSize = 4; } else { columnSize = 2; } } else { switch ((ColumnKindId) columnKind) { case ColumnKindId.Byte: columnSize = 1; break; case ColumnKindId.Short: case ColumnKindId.UShort: columnSize = 2; break; case ColumnKindId.Long: case ColumnKindId.ULong: columnSize = 4; break; case ColumnKindId.String: columnSize = this.stringIndexSize; break; case ColumnKindId.Guid: columnSize = this.guidIndexSize; break; case ColumnKindId.Blob: columnSize = this.blobIndexSize; break; default: throw new IllegalMetaDataFormatException("Unexpected schema kind: "+columnKind); } } // Save away the size and offset columnSizes[columnIndex] = columnSize; columnOffsets[columnIndex] = columnOffset; // Align to 2 bytes columnSize += (byte) (columnSize & 1); columnOffset += columnSize; } this.tableRowSizes[tableIndex] = columnOffset; tableSize += columnOffset * this.countArray[tableIndex]; } return tableSize; } private String getString(int stringIndex) { int limit = this.stringStreamBuffer.Length; if (stringIndex < 0 || stringIndex >= limit) { Console.WriteLine("Cannot find string "+stringIndex); return null; } else { int endIndex = stringIndex; while (this.stringStreamBuffer[endIndex] != 0) { endIndex++; } return stringEncoding.GetString(this.stringStreamBuffer, stringIndex, endIndex - stringIndex); } } private byte[] getBlobBytes(int blobIndex) { byte headerByte = this.blobStreamBuffer[blobIndex]; int size, startIndex; if ((headerByte & 0x80) == 0x00) { size = headerByte; startIndex = blobIndex+1; } else if ((headerByte & 0x40) == 0x00) { size = (((headerByte & 0x3f) << 8) | this.blobStreamBuffer[blobIndex+1]); startIndex = blobIndex+2; } else { size = (((headerByte & 0x3f) << 24) | (this.blobStreamBuffer[blobIndex+1] << 16) | (this.blobStreamBuffer[blobIndex+2] << 8) | (this.blobStreamBuffer[blobIndex+3])); startIndex = blobIndex+4; } byte[] buffer = new byte[size]; System.Array.Copy(this.blobStreamBuffer, startIndex, buffer, 0, size); return buffer; } private byte[] getResourceBytes(int offset) { int size = ((this.resourceBuffer[offset]) | (this.resourceBuffer[offset+1] << 8) | (this.resourceBuffer[offset+2] << 16) | (this.resourceBuffer[offset+3] << 24)); byte[] buffer = new byte[size]; System.Array.Copy(this.resourceBuffer, offset+4, buffer, 0, size); return buffer; } private Signature getSignature(int signatureIndex) { byte[] buffer = this.getBlobBytes(signatureIndex); return new SignatureBuffer(buffer); } private byte[] getValueBuffer(int valueIndex) { return this.getBlobBytes(valueIndex); } private MarshalSpec getNativeType(int nativeTypeIndex) { byte[] buffer = this.getBlobBytes(nativeTypeIndex); return MarshalSpec.Create(buffer); } private byte[] getPublicKey(int publicKeyIndex) { return this.getBlobBytes(publicKeyIndex); } private MetaDataBlob getPermissionSet(int permissionSetIndex) { // BUGBUG return new MetaDataBlob(this.getBlobBytes(permissionSetIndex)); } private byte[] getHashValue(int hashValueIndex) { return this.getBlobBytes(hashValueIndex); } private Guid getGuid(int guidIndex) { if (guidIndex < 0 || guidIndex >= this.guidArray.Length) { Console.WriteLine("Cannot find GUID "+guidIndex); return Guid.Empty; } else { return this.guidArray[guidIndex]; } } private MetaDataObject getObjectFromTableSet(int codedIndex, CodeToken codeToken) { if (codedIndex == 0) { return null; } int codeCount = CodeTokenTypeLists[(int) codeToken].Length; int kind = codedIndex & MaskForCountArray[codeCount]; int index = codedIndex >> BitsForCountArray[codeCount]; TokenType tokenType = CodeTokenTypeLists[(int) codeToken][kind]; MetaDataObject[] array = this.metaDataTable[(int) tokenType >> 24]; if (array == null) { Console.WriteLine("Missing table for kind "+kind+" of "+codeToken); return null; } else { return array[index-1]; } } private void InitializeMetaDataTables(BinaryReader reader) { this.metaDataTable = new MetaDataObject[(int) MetaDataTableIndices.Count][]; // First read in what goes in the tables this.initializeModuleTable(reader); this.initializeTypeRefTable(reader); this.initializeTypeDefTable(reader); this.initializeFieldPtrTable(reader); this.initializeFieldTable(reader); this.initializeMethodPtrTable(reader); this.initializeMethodTable(reader); this.initializeParamPtrTable(reader); this.initializeParamTable(reader); this.initializeInterfaceImplTable(reader); this.initializeMemberRefTable(reader); this.initializeConstantTable(reader); this.initializeCustomAttributeTable(reader); this.initializeFieldMarshalTable(reader); this.initializeDeclSecurityTable(reader); this.initializeClassLayoutTable(reader); this.initializeFieldLayoutTable(reader); this.initializeStandAloneSigTable(reader); this.initializeEventMapTable(reader); this.initializeEventPtrTable(reader); this.initializeEventTable(reader); this.initializePropertyMapTable(reader); this.initializePropertyPtrTable(reader); this.initializePropertyTable(reader); this.initializeMethodSemanticsTable(reader); this.initializeMethodImplTable(reader); this.initializeModuleRefTable(reader); this.initializeTypeSpecTable(reader); this.initializeImplMapTable(reader); this.initializeFieldRVATable(reader); this.initializeENCLogTable(reader); this.initializeENCMapTable(reader); this.initializeAssemblyTable(reader); this.initializeAssemblyProcessorTable(reader); this.initializeAssemblyOSTable(reader); this.initializeAssemblyRefTable(reader); this.initializeAssemblyRefProcessorTable(reader); this.initializeAssemblyRefOSTable(reader); this.initializeFileTable(reader); this.initializeExportedTypeTable(reader); this.initializeManifestResourceTable(reader); this.initializeNestedClassTable(reader); this.initializeGenericParamTable(reader); this.initializeMethodSpecTable(reader); this.initializeGenericParamConstraintTable(reader); this.initializeRelocationTable(); this.initializeVtableFixupTable(); this.initializeDelayIATTable(); // Then resolve references between tables this.resolveModuleReferences(); this.resolveTypeRefReferences(); this.resolveTypeDefReferences(); this.resolveFieldPtrReferences(); this.resolveFieldReferences(); this.resolveMethodPtrReferences(); this.resolveMethodReferences(); this.resolveParamPtrReferences(); this.resolveParamReferences(); this.resolveInterfaceImplReferences(); this.resolveMemberRefReferences(); this.resolveConstantReferences(); this.resolveCustomAttributeReferences(); this.resolveFieldMarshalReferences(); this.resolveDeclSecurityReferences(); this.resolveClassLayoutReferences(); this.resolveFieldLayoutReferences(); this.resolveStandAloneSigReferences(); this.resolveEventMapReferences(); this.resolveEventPtrReferences(); this.resolveEventReferences(); this.resolvePropertyMapReferences(); this.resolvePropertyPtrReferences(); this.resolvePropertyReferences(); this.resolveMethodSemanticsReferences(); this.resolveMethodImplReferences(); this.resolveModuleRefReferences(); this.resolveTypeSpecReferences(); this.resolveImplMapReferences(); this.resolveFieldRVAReferences(); this.resolveENCLogReferences(); this.resolveENCMapReferences(); this.resolveAssemblyReferences(); this.resolveAssemblyProcessorReferences(); this.resolveAssemblyOSReferences(); this.resolveAssemblyRefReferences(); this.resolveAssemblyRefProcessorReferences(); this.resolveAssemblyRefOSReferences(); this.resolveFileReferences(); this.resolveExportedTypeReferences(); this.resolveManifestResourceReferences(); this.resolveNestedClassReferences(); this.resolveGenericParamReferences(); this.resolveMethodSpecReferences(); this.resolveGenericParamConstraintReferences(); } private void initializeModuleTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Module]; this.moduleArray = new MetaDataModule[count]; this.metaDataTable[(int) MetaDataTableIndices.Module] = this.moduleArray; for (int i = 0; i < count; i++) { short generation = reader.ReadInt16(); int nameIndex, mvid, encodingIndex, encodingBaseIdIndex; if (this.stringIndexSize == 4) { nameIndex = reader.ReadInt32(); } else { nameIndex = reader.ReadUInt16(); } String name = this.getString(nameIndex); if (this.guidIndexSize == 4) { mvid = reader.ReadInt32(); encodingIndex = reader.ReadInt32(); encodingBaseIdIndex = reader.ReadInt32(); } else { mvid = reader.ReadUInt16(); encodingIndex = reader.ReadUInt16(); encodingBaseIdIndex = reader.ReadUInt16(); } Guid encoding = this.getGuid(encodingIndex); Guid encodingBaseId = this.getGuid(encodingBaseIdIndex); this.moduleArray[i] = new MetaDataModule(generation, name, mvid, encodingIndex, encoding, encodingBaseIdIndex, encodingBaseId); } } // Access Methods internal String getUserString(int stringIndex) { byte headerByte = this.userStringStreamBuffer[stringIndex]; int size, startIndex; if ((headerByte & 0x80) == 0x00) { size = headerByte; startIndex = stringIndex + 1; } else if ((headerByte & 0x40) == 0x00) { size = (((headerByte & 0x3f) << 8) | this.userStringStreamBuffer[stringIndex + 1]); startIndex = stringIndex + 2; } else { size = (((headerByte & 0x3f) << 24) | (this.userStringStreamBuffer[stringIndex+1] << 16) | (this.userStringStreamBuffer[stringIndex+2] << 8) | (this.userStringStreamBuffer[stringIndex+3])); startIndex = stringIndex+4; } int stringSize = size/2; char[] chars = new char[stringSize]; for (int i = 0; i < stringSize; i++) { char ch = (char ) (this.userStringStreamBuffer[startIndex] | this.userStringStreamBuffer[startIndex+1] << 8); chars[i] = ch; startIndex += 2; } return new String(chars); } internal MetaDataObject getTypeDefOrRef(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.TypeDefOrRef); } internal MetaDataObject getHasConstant(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.HasConstant); } internal MetaDataObject getHasCustomAttribute(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.HasCustomAttribute); } internal MetaDataObject getHasFieldMarshal(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.HasFieldMarshal); } internal MetaDataObject getHasDeclSecurity(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.HasDeclSecurity); } internal MetaDataObject getMemberRefParent(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.MemberRefParent); } internal MetaDataObject getHasSemantic(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.HasSemantic); } internal MetaDataObject getMethodDefOrRef(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.MethodDefOrRef); } internal MetaDataObject getMemberForwarded(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.MemberForwarded); } internal MetaDataObject getImplementation(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.Implementation); } internal MetaDataObject getCustomAttributeType(int codedIndex) { return this.getObjectFromTableSet(codedIndex, CodeToken.CustomAttributeType); } internal MetaDataObject getResolutionScope(int resolutionIndex) { return this.getObjectFromTableSet(resolutionIndex, CodeToken.ResolutionScope); } internal MetaDataObject getTypeOrMethodDef(int resolutionIndex) { return this.getObjectFromTableSet(resolutionIndex, CodeToken.TypeOrMethodDef); } internal MetaDataObject getObjectFromToken(int token) { int type = token >> 24; int index = token & 0x00FFFFFF; return this.metaDataTable[type][index-1]; } internal MetaDataTypeDefinition getTypeDef(int typeDefIndex) { if (typeDefIndex < 1 || typeDefIndex > this.typeDefArray.Length) { Console.WriteLine("Cannot find TypeDef "+typeDefIndex); return null; } else { return this.typeDefArray[typeDefIndex-1]; } } internal MetaDataField getField(int fieldIndex) { if (fieldIndex < 1 || fieldIndex > this.fieldArray.Length) { Console.WriteLine("Cannot find field "+fieldIndex); return null; } else { return this.fieldArray[fieldIndex-1]; } } internal MetaDataField[] getFields(int startIndex, int count) { if (count <= 0) { return emptyFieldArray; } MetaDataField[] result = new MetaDataField[count]; Array.Copy(this.fieldArray, startIndex-1, result, 0, count); return result; } internal MetaDataMethod getMethod(int methodIndex) { if (methodIndex < 1 || methodIndex > this.methodArray.Length) { Console.WriteLine("Cannot find method "+methodIndex); return null; } else { return this.methodArray[methodIndex-1]; } } internal MetaDataMethod[] getMethods(int startIndex, int count) { if (count <= 0) { return emptyMethodArray; } MetaDataMethod[] result = new MetaDataMethod[count]; Array.Copy(this.methodArray, startIndex-1, result, 0, count); return result; } internal MetaDataParam getParam(int paramIndex) { if (paramIndex < 1 || paramIndex > this.paramArray.Length) { Console.WriteLine("Cannot find parameter "+paramIndex); return null; } else { return this.paramArray[paramIndex-1]; } } internal MetaDataParam[] getParams(int startIndex, int count) { if (count <= 0) { return emptyParamArray; } if (startIndex < this.paramArray.Length && this.getParam(startIndex).Sequence == 0) { startIndex++; count--; } for (int i = 0; i < count; i++) { if (startIndex + i < this.paramArray.Length) { if (this.getParam(startIndex + i).Sequence == 0) { throw new Exception("Asking for non-owned parameters"); } } } MetaDataParam[] result = new MetaDataParam[count]; Array.Copy(this.paramArray, startIndex-1, result, 0, count); return result; } internal MetaDataEvent getEvent(int eventIndex) { if (eventIndex < 1 || eventIndex > this.eventArray.Length) { Console.WriteLine("Cannot find event "+eventIndex); return null; } else { return this.eventArray[eventIndex-1]; } } internal MetaDataProperty getProperty(int propertyIndex) { if (propertyIndex < 1 || propertyIndex > this.propertyArray.Length) { Console.WriteLine("Cannot find property "+propertyIndex); return null; } else { return this.propertyArray[propertyIndex-1]; } } internal MetaDataModuleRef getModuleRef(int moduleRefIndex) { if (moduleRefIndex < 1 || moduleRefIndex > this.moduleRefArray.Length) { Console.WriteLine("Cannot find moduleref "+moduleRefIndex); return null; } else { return this.moduleRefArray[moduleRefIndex-1]; } } internal MetaDataAssemblyRef getAssemblyRef(int assemblyRefIndex) { if (assemblyRefIndex < 1 || assemblyRefIndex > this.assemblyRefArray.Length) { Console.WriteLine("Cannot find assemblyref "+assemblyRefIndex); return null; } else { return this.assemblyRefArray[assemblyRefIndex-1]; } } internal MetaDataGenericParam getGenericParam(int genericParamIndex) { if (genericParamIndex < 1 || genericParamIndex > this.genericParamArray.Length) { Console.WriteLine("Cannot find genericparam "+genericParamIndex); return null; } return this.genericParamArray[genericParamIndex-1]; } // Methods for initializing the tables and table objects private void resolveModuleReferences() { // foreach (MetaDataModule module in this.moduleArray) { // Console.WriteLine(module.ToStringLong()); // } } private void initializeTypeRefTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.TypeRef]; this.typeRefArray = new MetaDataTypeReference[count]; this.metaDataTable[(int) MetaDataTableIndices.TypeRef] = this.typeRefArray; byte bigScopeIndexSize = this.tableColumnSizes[(int)MetaDataTableIndices.TypeRef][0]; for (int i = 0; i < count; i++) { int resolutionScopeIndex = ((bigScopeIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int nameIndex, nameSpaceIndex; if (this.stringIndexSize == 4) { nameIndex = reader.ReadInt32(); nameSpaceIndex = reader.ReadInt32(); } else { nameIndex = reader.ReadUInt16(); nameSpaceIndex = reader.ReadUInt16(); } String name = this.getString(nameIndex); String nameSpace = this.getString(nameSpaceIndex); this.typeRefArray[i] = new MetaDataTypeReference(resolutionScopeIndex, name, nameSpace); } } private void resolveTypeRefReferences() { foreach (MetaDataTypeReference typeRef in this.typeRefArray) { typeRef.resolveReferences(this); // Console.WriteLine(typeRef.ToStringLong()); } } private void initializeTypeDefTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.TypeDef]; this.typeDefArray = new MetaDataTypeDefinition[count]; this.metaDataTable[(int) MetaDataTableIndices.TypeDef] = this.typeDefArray; byte extendsSize = this.tableColumnSizes[(int)MetaDataTableIndices.TypeDef][3]; byte fieldSize = this.tableColumnSizes[(int)MetaDataTableIndices.TypeDef][4]; byte methodSize = this.tableColumnSizes[(int)MetaDataTableIndices.TypeDef][5]; for (int i = 0; i < count; i++) { TypeAttributes flags = (TypeAttributes) reader.ReadInt32(); int nameIndex, nameSpaceIndex; if (this.stringIndexSize == 4) { nameIndex = reader.ReadInt32(); nameSpaceIndex = reader.ReadInt32(); } else { nameIndex = reader.ReadUInt16(); nameSpaceIndex = reader.ReadUInt16(); } String name = this.getString(nameIndex); String nameSpace = this.getString(nameSpaceIndex); int extendsIndex = ((extendsSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int fieldIndex = ((fieldSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int methodIndex = ((methodSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.typeDefArray[i] = new MetaDataTypeDefinition(flags, name, nameSpace, extendsIndex, fieldIndex, methodIndex); } } private void resolveTypeDefReferences() { int fieldCount = this.fieldArray.Length; int methodCount = this.methodArray.Length; MetaDataTypeDefinition[] fieldOwners = new MetaDataTypeDefinition[fieldCount+2]; MetaDataTypeDefinition[] methodOwners = new MetaDataTypeDefinition[methodCount+2]; foreach (MetaDataTypeDefinition typedef in this.typeDefArray) { typedef.registerReferences(fieldCount, methodCount, fieldOwners, methodOwners); } MetaDataTypeDefinition current = null; for (int i = 0; i <= fieldCount; i++) { if (fieldOwners[i] == null) { fieldOwners[i] = current; } else { current = fieldOwners[i]; } } current = null; for (int i = 0; i <= methodCount; i++) { if (methodOwners[i] == null) { methodOwners[i] = current; } else { current = methodOwners[i]; } } foreach (MetaDataTypeDefinition typedef in this.typeDefArray) { typedef.resolveReferences(this, fieldOwners, methodOwners); } } private void initializeFieldPtrTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.FieldPtr]; this.fieldPtrArray = new MetaDataFieldPtr[count]; this.metaDataTable[(int) MetaDataTableIndices.FieldPtr] = this.fieldPtrArray; byte indexSize = this.tableColumnSizes[(int)MetaDataTableIndices.FieldPtr][0]; for (int i = 0; i < count; i++) { int fieldIndex = ((indexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.fieldPtrArray[i] = new MetaDataFieldPtr(fieldIndex); } } private void resolveFieldPtrReferences() { foreach (MetaDataFieldPtr fieldPtr in this.fieldPtrArray) { fieldPtr.resolveReferences(this); // Console.WriteLine(fieldPtr); } } private void initializeFieldTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Field]; this.fieldArray = new MetaDataField[count]; this.metaDataTable[(int) MetaDataTableIndices.Field] = this.fieldArray; for (int i = 0; i < count; i++) { short flags = reader.ReadInt16(); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int signatureIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); Signature signature = this.getSignature(signatureIndex); this.fieldArray[i] = new MetaDataField(flags, name, signature); } } private void resolveFieldReferences() { foreach (MetaDataField field in this.fieldArray) { field.resolveReferences(this); // Console.WriteLine(field.ToStringLong()); } } private void initializeMethodPtrTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.MethodPtr]; this.methodPtrArray = new MetaDataMethodPtr[count]; this.metaDataTable[(int) MetaDataTableIndices.MethodPtr] = this.methodPtrArray; byte indexSize = this.tableColumnSizes[(int)MetaDataTableIndices.MethodPtr][0]; for (int i = 0; i < count; i++) { int methodIndex = ((indexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.methodPtrArray[i] = new MetaDataMethodPtr(methodIndex); } } private void resolveMethodPtrReferences() { foreach (MetaDataMethodPtr methodPtr in this.methodPtrArray) { methodPtr.resolveReferences(this); // Console.WriteLine(methodPtr.ToStringLong()); } } private void initializeMethodTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Method]; this.methodArray = new MetaDataMethod[count]; this.metaDataTable[(int) MetaDataTableIndices.Method] = this.methodArray; byte paramSize = this.tableColumnSizes[(int)MetaDataTableIndices.Method][5]; for (int i = 0; i < count; i++) { int rva = reader.ReadInt32(); short implFlags = reader.ReadInt16(); short flags = reader.ReadInt16(); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int signatureIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); Signature signature = this.getSignature(signatureIndex); int paramIndex = ((paramSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.methodArray[i] = new MetaDataMethod(rva, implFlags, flags, name, signature, paramIndex); } } private void resolveMethodReferences() { int paramCount = this.paramArray.Length; MetaDataMethod[] paramOwners = new MetaDataMethod[paramCount+2]; foreach (MetaDataMethod method in this.methodArray) { method.registerReferences(paramCount, paramOwners); } MetaDataMethod current = null; for (int i = 1; i <= paramCount; i++) { if (paramOwners[i] == null) { paramOwners[i] = current; } else { current = paramOwners[i]; } } foreach (MetaDataMethod method in this.methodArray) { method.resolveReferences(this, paramOwners); // Console.WriteLine(method.ToStringLong()); } } private void initializeParamPtrTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ParamPtr]; this.paramPtrArray = new MetaDataParamPtr[count]; this.metaDataTable[(int) MetaDataTableIndices.ParamPtr] = this.paramPtrArray; byte indexSize = this.tableColumnSizes[(int)MetaDataTableIndices.ParamPtr][0]; for (int i = 0; i < count; i++) { int paramIndex = ((indexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.paramPtrArray[i] = new MetaDataParamPtr(paramIndex); } } private void resolveParamPtrReferences() { foreach (MetaDataParamPtr paramPtr in this.paramPtrArray) { paramPtr.resolveReferences(this); // Console.WriteLine(paramPtr.ToStringLong()); } } private void initializeParamTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Param]; this.paramArray = new MetaDataParam[count]; this.metaDataTable[(int) MetaDataTableIndices.Param] = this.paramArray; for (int i = 0; i < count; i++) { short flags = reader.ReadInt16(); short sequence = reader.ReadInt16(); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); this.paramArray[i] = new MetaDataParam(flags, sequence, name); } } private void resolveParamReferences() { // foreach (MetaDataParam param in this.paramArray) { // Console.WriteLine(param.ToStringLong()); // } } private void initializeInterfaceImplTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.InterfaceImpl]; this.interfaceImplArray = new MetaDataInterfaceImpl[count]; this.metaDataTable[(int) MetaDataTableIndices.InterfaceImpl] = this.interfaceImplArray; int classSize = this.tableColumnSizes[(int)MetaDataTableIndices.InterfaceImpl][0]; int interfaceSize = this.tableColumnSizes[(int)MetaDataTableIndices.InterfaceImpl][1]; for (int i = 0; i < count; i++) { int classIndex = ((classSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int interfaceIndex = ((interfaceSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.interfaceImplArray[i] = new MetaDataInterfaceImpl(classIndex, interfaceIndex); } } private void resolveInterfaceImplReferences() { int typeDefCount = this.typeDefArray.Length; ArrayList[] interfaceListArray = new ArrayList[typeDefCount+1]; foreach (MetaDataInterfaceImpl interfaceImpl in this.interfaceImplArray) { interfaceImpl.resolveReferences(this, interfaceListArray); // Console.WriteLine(interfaceImpl.ToStringLong()); } for (int i = 1; i <= typeDefCount; i++) { MetaDataTypeDefinition classObject = this.getTypeDef(i); if (interfaceListArray[i] != null) { MetaDataObject[] interfaceArray = new MetaDataObject[interfaceListArray[i].Count]; interfaceListArray[i].CopyTo(interfaceArray); classObject.resolveReferences(interfaceArray); } else { classObject.resolveReferences(emptyInterfaceArray); } } } private void initializeMemberRefTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.MemberRef]; this.memberRefArray = new MetaDataMemberRef[count]; this.metaDataTable[(int) MetaDataTableIndices.MemberRef] = this.memberRefArray; int classSize = this.tableColumnSizes[(int)MetaDataTableIndices.MemberRef][0]; for (int i = 0; i < count; i++) { int classIndex = ((classSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int signatureIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); Signature signature = this.getSignature(signatureIndex); this.memberRefArray[i] = new MetaDataMemberRef(classIndex, name, signature); } } private void resolveMemberRefReferences() { foreach (MetaDataMemberRef memberRef in this.memberRefArray) { memberRef.resolveReferences(this); // Console.WriteLine(memberRef.ToStringLong()); } } private void initializeConstantTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Constant]; this.constantArray = new MetaDataConstant[count]; this.metaDataTable[(int) MetaDataTableIndices.Constant] = this.constantArray; int parentSize = this.tableColumnSizes[(int)MetaDataTableIndices.Constant][1]; for (int i = 0; i < count; i++) { ElementTypes type = (ElementTypes) reader.ReadByte(); byte padding = reader.ReadByte(); int parentIndex = ((parentSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int valueIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); byte[] valueBuffer = this.getValueBuffer(valueIndex); this.constantArray[i] = new MetaDataConstant(type, parentIndex, valueBuffer); } } private void resolveConstantReferences() { foreach (MetaDataConstant constant in this.constantArray) { constant.resolveReferences(this); MetaDataObject parent = constant.Parent; if (parent is MetaDataField) { ((MetaDataField) parent).resolveReferences(constant); } else if (parent is MetaDataParam) { ((MetaDataParam) parent).resolveReferences(constant); } else if (parent is MetaDataProperty) { ((MetaDataProperty) parent).resolveReferences(constant); } else { throw new IllegalMetaDataFormatException("Unexpected parent of constant: "+parent); } // Console.WriteLine(constant.ToStringLong()); } } private void initializeCustomAttributeTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.CustomAttribute]; this.customAttributeArray = new MetaDataCustomAttribute[count]; this.metaDataTable[(int) MetaDataTableIndices.CustomAttribute] = this.customAttributeArray; int parentSize = this.tableColumnSizes[(int)MetaDataTableIndices.CustomAttribute][0]; int typeSize = this.tableColumnSizes[(int)MetaDataTableIndices.CustomAttribute][1]; for (int i = 0; i < count; i++) { int parentIndex = ((parentSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int typeIndex = ((typeSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int valueIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MetaDataObject type = this.getCustomAttributeType(typeIndex); byte[] valueBuffer = this.getBlobBytes(valueIndex); this.customAttributeArray[i] = new MetaDataCustomAttribute(parentIndex, type, valueBuffer); } } private void resolveCustomAttributeReferences() { foreach (MetaDataCustomAttribute attribute in this.customAttributeArray) { attribute.resolveReferences(this); // Console.WriteLine(attribute.ToStringLong()); } } private void initializeFieldMarshalTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.FieldMarshal]; this.fieldMarshalArray = new MetaDataFieldMarshal[count]; this.metaDataTable[(int) MetaDataTableIndices.FieldMarshal] = this.fieldMarshalArray; int parentSize = this.tableColumnSizes[(int)MetaDataTableIndices.FieldMarshal][0]; for (int i = 0; i < count; i++) { int parentIndex = ((parentSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int nativeTypeIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MarshalSpec nativeType = this.getNativeType(nativeTypeIndex); this.fieldMarshalArray[i] = new MetaDataFieldMarshal(parentIndex, nativeType); } } private void resolveFieldMarshalReferences() { foreach (MetaDataFieldMarshal fieldMarshal in this.fieldMarshalArray) { fieldMarshal.resolveReferences(this); // Console.WriteLine(fieldMarshal.ToStringLong()); } } private void initializeDeclSecurityTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.DeclSecurity]; this.declSecurityArray = new MetaDataDeclSecurity[count]; this.metaDataTable[(int) MetaDataTableIndices.DeclSecurity] = this.declSecurityArray; int parentSize = this.tableColumnSizes[(int) MetaDataTableIndices.DeclSecurity][1]; for (int i = 0; i < count; i++) { short action = reader.ReadInt16(); int parentIndex = ((parentSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int permissionSetIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MetaDataBlob permissionSet = this.getPermissionSet(permissionSetIndex); this.declSecurityArray[i] = new MetaDataDeclSecurity(action, parentIndex, permissionSet); } } private void resolveDeclSecurityReferences() { foreach (MetaDataDeclSecurity declSecurity in this.declSecurityArray) { declSecurity.resolveReferences(this); // Console.WriteLine(declSecurity.ToStringLong()); } } private void initializeClassLayoutTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ClassLayout]; this.classLayoutArray = new MetaDataClassLayout[count]; this.metaDataTable[(int) MetaDataTableIndices.ClassLayout] = this.classLayoutArray; int parentSize = this.tableColumnSizes[(int) MetaDataTableIndices.ClassLayout][2]; for (int i = 0; i < count; i++) { short packingSize = reader.ReadInt16(); int classSize = reader.ReadInt32(); int parentIndex = ((parentSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.classLayoutArray[i] = new MetaDataClassLayout(packingSize, classSize, parentIndex); } } private void resolveClassLayoutReferences() { foreach (MetaDataClassLayout classLayout in this.classLayoutArray) { classLayout.resolveReferences(this); // Console.WriteLine(classLayout.ToStringLong()); } } private void initializeFieldLayoutTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.FieldLayout]; this.fieldLayoutArray = new MetaDataFieldLayout[count]; this.metaDataTable[(int) MetaDataTableIndices.FieldLayout] = this.fieldLayoutArray; int fieldSize = this.tableColumnSizes[(int) MetaDataTableIndices.FieldLayout][1]; for (int i = 0; i < count; i++) { int offset = reader.ReadInt32(); int fieldIndex = ((fieldSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MetaDataField field = this.getField(fieldIndex); MetaDataFieldLayout fieldLayout = new MetaDataFieldLayout(offset, field); field.resolveReferences(fieldLayout); this.fieldLayoutArray[i] = fieldLayout; } } private void resolveFieldLayoutReferences() { // foreach (MetaDataFieldLayout fieldLayout in // this.fieldLayoutArray) { // Console.WriteLine(fieldLayout.ToStringLong()); // } } private void initializeStandAloneSigTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.StandAloneSig]; this.standAloneSigArray = new MetaDataStandAloneSig[count]; this.metaDataTable[(int) MetaDataTableIndices.StandAloneSig] = this.standAloneSigArray; int signatureSize = this.tableColumnSizes[(int) MetaDataTableIndices.StandAloneSig][0]; for (int i = 0; i < count; i++) { int signatureIndex = ((signatureSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); Signature signature = this.getSignature(signatureIndex); this.standAloneSigArray[i] = new MetaDataStandAloneSig(signature); } } private void resolveStandAloneSigReferences() { foreach (MetaDataStandAloneSig standAloneSig in this.standAloneSigArray) { standAloneSig.resolveReferences(this); // Console.WriteLine(standAloneSig.ToStringLong()); } } private void initializeEventMapTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.EventMap]; this.eventMapArray = new MetaDataEventMap[count]; this.metaDataTable[(int) MetaDataTableIndices.EventMap] = this.eventMapArray; int parentSize = this.tableColumnSizes[(int) MetaDataTableIndices.EventMap][0]; int eventListSize = this.tableColumnSizes[(int) MetaDataTableIndices.EventMap][1]; for (int i = 0; i < count; i++) { int parentIndex = ((parentSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int eventListIndex = ((eventListSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.eventMapArray[i] = new MetaDataEventMap(parentIndex, eventListIndex); } } private void resolveEventMapReferences() { foreach (MetaDataEventMap eventMap in this.eventMapArray) { eventMap.resolveReferences(this); // Console.WriteLine(eventMap.ToStringLong()); } } private void initializeEventPtrTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.EventPtr]; this.eventPtrArray = new MetaDataEventPtr[count]; this.metaDataTable[(int) MetaDataTableIndices.EventPtr] = this.eventPtrArray; int eventSize = this.tableColumnSizes[(int) MetaDataTableIndices.EventPtr][0]; for (int i = 0; i < count; i++) { int eventIndex = ((eventSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.eventPtrArray[i] = new MetaDataEventPtr(eventIndex); } } private void resolveEventPtrReferences() { foreach (MetaDataEventPtr eventPtr in this.eventPtrArray) { eventPtr.resolveReferences(this); // Console.WriteLine(eventPtr.ToStringLong()); } } private void initializeEventTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Event]; this.eventArray = new MetaDataEvent[count]; this.metaDataTable[(int) MetaDataTableIndices.Event] = this.eventArray; int eventTypeSize = this.tableColumnSizes[(int) MetaDataTableIndices.Event][2]; for (int i = 0; i < count; i++) { short eventFlags = reader.ReadInt16(); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int eventTypeIndex = ((eventTypeSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.eventArray[i] = new MetaDataEvent(eventFlags, name, eventTypeIndex); } } private void resolveEventReferences() { foreach (MetaDataEvent eventObject in this.eventArray) { eventObject.resolveReferences(this); // Console.WriteLine(eventObject.ToStringLong()); } } private void initializePropertyMapTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.PropertyMap]; this.propertyMapArray = new MetaDataPropertyMap[count]; this.metaDataTable[(int) MetaDataTableIndices.PropertyMap] = this.propertyMapArray; int parentSize = this.tableColumnSizes[(int) MetaDataTableIndices.PropertyMap][0]; int propertyListSize = this.tableColumnSizes[(int) MetaDataTableIndices.PropertyMap][1]; for (int i = 0; i < count; i++) { int parentIndex = ((parentSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int propertyListIndex = ((propertyListSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.propertyMapArray[i] = new MetaDataPropertyMap(parentIndex, propertyListIndex); } } private void resolvePropertyMapReferences() { foreach (MetaDataPropertyMap propertyMap in this.propertyMapArray) { propertyMap.resolveReferences(this); // Console.WriteLine(propertyMap.ToStringLong()); } } private void initializePropertyPtrTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.PropertyPtr]; this.propertyPtrArray = new MetaDataPropertyPtr[count]; this.metaDataTable[(int) MetaDataTableIndices.PropertyPtr] = this.propertyPtrArray; int propertySize = this.tableColumnSizes[(int) MetaDataTableIndices.PropertyPtr][0]; for (int i = 0; i < count; i++) { int propertyIndex = ((propertySize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.propertyPtrArray[i] = new MetaDataPropertyPtr(propertyIndex); } } private void resolvePropertyPtrReferences() { foreach (MetaDataPropertyPtr propertyPtr in this.propertyPtrArray) { propertyPtr.resolveReferences(this); // Console.WriteLine(propertyPtr.ToStringLong()); } } private void initializePropertyTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Property]; this.propertyArray = new MetaDataProperty[count]; this.metaDataTable[(int) MetaDataTableIndices.Property] = this.propertyArray; for (int i = 0; i < count; i++) { short flags = reader.ReadInt16(); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int typeIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); Signature type = this.getSignature(typeIndex); this.propertyArray[i] = new MetaDataProperty(flags, name, type); } } private void resolvePropertyReferences() { foreach (MetaDataProperty property in this.propertyArray) { property.resolveReferences(this); // Console.WriteLine(property.ToStringLong()); } } private void initializeMethodSemanticsTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.MethodSemantics]; this.methodSemanticsArray = new MetaDataMethodSemantics[count]; this.metaDataTable[(int) MetaDataTableIndices.MethodSemantics] = this.methodSemanticsArray; int methodSize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodSemantics][1]; int associationSize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodSemantics][2]; for (int i = 0; i < count; i++) { short semantic = reader.ReadInt16(); int methodIndex = ((methodSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int associationIndex = ((associationSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.methodSemanticsArray[i] = new MetaDataMethodSemantics(semantic, methodIndex, associationIndex); } } private void resolveMethodSemanticsReferences() { foreach (MetaDataMethodSemantics methodSemantics in this.methodSemanticsArray) { methodSemantics.resolveReferences(this); // Console.WriteLine(methodSemantics.ToStringLong()); } } private void initializeMethodImplTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.MethodImpl]; this.methodImplArray = new MetaDataMethodImpl[count]; this.metaDataTable[(int) MetaDataTableIndices.MethodImpl] = this.methodImplArray; int classSize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodImpl][0]; int bodySize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodImpl][1]; int declarationSize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodImpl][2]; for (int i = 0; i < count; i++) { int classIndex = ((classSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int bodyIndex = ((bodySize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int declarationIndex = ((declarationSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.methodImplArray[i] = new MetaDataMethodImpl(classIndex, bodyIndex, declarationIndex); } } private void resolveMethodImplReferences() { foreach (MetaDataMethodImpl methodImpl in this.methodImplArray) { methodImpl.resolveReferences(this); // Console.WriteLine(methodImpl.ToStringLong()); } } private void initializeModuleRefTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ModuleRef]; this.moduleRefArray = new MetaDataModuleRef[count]; this.metaDataTable[(int) MetaDataTableIndices.ModuleRef] = this.moduleRefArray; for (int i = 0; i < count; i++) { int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); this.moduleRefArray[i] = new MetaDataModuleRef(name); } } private void resolveModuleRefReferences() { // foreach (MetaDataModuleRef moduleRef in this.moduleRefArray) { // Console.WriteLine(moduleRef.ToStringLong()); // } } private void initializeTypeSpecTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.TypeSpec]; this.typeSpecArray = new MetaDataTypeSpec[count]; this.metaDataTable[(int) MetaDataTableIndices.TypeSpec] = this.typeSpecArray; for (int i = 0; i < count; i++) { int signatureIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); Signature signature = this.getSignature(signatureIndex); this.typeSpecArray[i] = new MetaDataTypeSpec(signature); } } private void resolveTypeSpecReferences() { foreach (MetaDataTypeSpec typeSpec in this.typeSpecArray) { typeSpec.resolveReferences(this); // Console.WriteLine(typeSpec.ToStringLong()); } } private void initializeImplMapTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ImplMap]; this.implMapArray = new MetaDataImplMap[count]; this.metaDataTable[(int) MetaDataTableIndices.ImplMap] = this.implMapArray; int memberForwardedSize = this.tableColumnSizes[(int) MetaDataTableIndices.ImplMap][1]; int importScopeSize = this.tableColumnSizes[(int) MetaDataTableIndices.ImplMap][3]; for (int i = 0; i < count; i++) { short flags = reader.ReadInt16(); int memberForwardedIndex = ((memberForwardedSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int importNameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String importName = this.getString(importNameIndex); int importScopeIndex = ((importScopeSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.implMapArray[i] = new MetaDataImplMap(flags, memberForwardedIndex, importName, importScopeIndex); } } private void resolveImplMapReferences() { foreach (MetaDataImplMap implMap in this.implMapArray) { implMap.resolveReferences(this); // Console.WriteLine(implMap.ToStringLong()); } } private void initializeFieldRVATable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.FieldRVA]; this.fieldRVAArray = new MetaDataFieldRVA[count]; this.metaDataTable[(int) MetaDataTableIndices.FieldRVA] = this.fieldRVAArray; int fieldSize = this.tableColumnSizes[(int) MetaDataTableIndices.FieldRVA][1]; for (int i = 0; i < count; i++) { int rva = reader.ReadInt32(); int fieldIndex = ((fieldSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MetaDataField field = this.getField(fieldIndex); this.fieldRVAArray[i] = new MetaDataFieldRVA(rva, field); } } private void resolveFieldRVAReferences() { foreach (MetaDataFieldRVA fieldRVA in this.fieldRVAArray) { // Console.WriteLine(fieldRVA.ToStringLong()); // Console.WriteLine(fieldRVA.Field.ToStringLong()); fieldRVA.resolveReferences(this, this.peLoader, this.fileStream); // Console.WriteLine(fieldRVA.ToStringLong()); } } private void initializeENCLogTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ENCLog]; if (count != 0) { throw new IllegalMetaDataFormatException("Found ENCLog entries"); } } private void resolveENCLogReferences() { // Do nothing } private void initializeENCMapTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ENCMap]; if (count != 0) { throw new IllegalMetaDataFormatException("Found ENCMap entries"); } } private void resolveENCMapReferences() { // Do nothing } private void initializeAssemblyTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.Assembly]; this.assemblyArray = new MetaDataAssembly[count]; this.metaDataTable[(int) MetaDataTableIndices.Assembly] = this.assemblyArray; for (int i = 0; i < count; i++) { int hashAlgorithmId = reader.ReadInt32(); short majorVersion = reader.ReadInt16(); short minorVersion = reader.ReadInt16(); short buildNumber = reader.ReadInt16(); short revisionNumber = reader.ReadInt16(); int flags = reader.ReadInt32(); int publicKeyIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); byte[] publicKey = this.getPublicKey(publicKeyIndex); int nameIndex, localeIndex; if (this.stringIndexSize == 4) { nameIndex = reader.ReadInt32(); localeIndex = reader.ReadInt32(); } else { nameIndex = reader.ReadUInt16(); localeIndex = reader.ReadUInt16(); } String name = this.getString(nameIndex); String locale = this.getString(localeIndex); this.assemblyArray[i] = new MetaDataAssembly(hashAlgorithmId, majorVersion, minorVersion, buildNumber, revisionNumber, flags, publicKey, name, locale); } } private void resolveAssemblyReferences() { // foreach (MetaDataAssembly assembly in this.assemblyArray) { // Console.WriteLine(assembly.ToStringLong()); // } } private void initializeAssemblyProcessorTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.AssemblyProcessor]; this.assemblyProcessorArray = new MetaDataAssemblyProcessor[count]; this.metaDataTable[(int) MetaDataTableIndices.AssemblyProcessor] = this.assemblyProcessorArray; for (int i = 0; i < count; i++) { int processor = reader.ReadInt32(); this.assemblyProcessorArray[i] = new MetaDataAssemblyProcessor(processor); } } private void resolveAssemblyProcessorReferences() { // foreach (MetaDataAssemblyProcessor assemblyProcessor in // this.assemblyProcessorArray) { // Console.WriteLine(assemblyProcessor.ToStringLong()); // } } private void initializeAssemblyOSTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.AssemblyOS]; this.assemblyOSArray = new MetaDataAssemblyOS[count]; this.metaDataTable[(int) MetaDataTableIndices.AssemblyOS] = this.assemblyOSArray; for (int i = 0; i < count; i++) { int platformID = reader.ReadInt32(); int majorVersion = reader.ReadInt32(); int minorVersion = reader.ReadInt32(); this.assemblyOSArray[i] = new MetaDataAssemblyOS(platformID, majorVersion, minorVersion); } } private void resolveAssemblyOSReferences() { // foreach (MetaDataAssemblyOS assemblyOS in // this.assemblyOSArray) { // Console.WriteLine(assemblyOS.ToStringLong()); // } } private void initializeAssemblyRefTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.AssemblyRef]; this.assemblyRefArray = new MetaDataAssemblyRef[count]; this.metaDataTable[(int) MetaDataTableIndices.AssemblyRef] = this.assemblyRefArray; for (int i = 0; i < count; i++) { short majorVersion = reader.ReadInt16(); short minorVersion = reader.ReadInt16(); short buildNumber = reader.ReadInt16(); short revisionNumber = reader.ReadInt16(); int flags = reader.ReadInt32(); int publicKeyIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); byte[] publicKey = this.getPublicKey(publicKeyIndex); int nameIndex, localeIndex; if (this.stringIndexSize == 4) { nameIndex = reader.ReadInt32(); localeIndex = reader.ReadInt32(); } else { nameIndex = reader.ReadUInt16(); localeIndex = reader.ReadUInt16(); } String name = this.getString(nameIndex); String locale = this.getString(localeIndex); int hashValueIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); byte[] hashValue = this.getHashValue(hashValueIndex); this.assemblyRefArray[i] = new MetaDataAssemblyRef(majorVersion, minorVersion, buildNumber, revisionNumber, flags, publicKey, name, locale, hashValue); } } private void resolveAssemblyRefReferences() { // foreach (MetaDataAssemblyRef assemblyRef in // this.assemblyRefArray) { // Console.WriteLine(assemblyRef.ToStringLong()); // } } private void initializeAssemblyRefProcessorTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.AssemblyRefProcessor]; this.assemblyRefProcessorArray = new MetaDataAssemblyRefProcessor[count]; this.metaDataTable[(int) MetaDataTableIndices.AssemblyRefProcessor] = this.assemblyRefProcessorArray; int assemblyRefSize = this.tableColumnSizes[(int) MetaDataTableIndices.AssemblyRefProcessor][1]; for (int i = 0; i < count; i++) { int processor = reader.ReadInt32(); int assemblyRefIndex = ((assemblyRefSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MetaDataAssemblyRef assemblyRef = this.getAssemblyRef(assemblyRefIndex); this.assemblyRefProcessorArray[i] = new MetaDataAssemblyRefProcessor(processor, assemblyRef); } } private void resolveAssemblyRefProcessorReferences() { // foreach (MetaDataAssemblyRefProcessor assemblyRefProcessor in // this.assemblyRefProcessorArray) { // Console.WriteLine(assemblyRefProcessor.ToStringLong()); // } } private void initializeAssemblyRefOSTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.AssemblyRefOS]; this.assemblyRefOSArray = new MetaDataAssemblyRefOS[count]; this.metaDataTable[(int) MetaDataTableIndices.AssemblyRefOS] = this.assemblyRefOSArray; int assemblyRefSize = this.tableColumnSizes[(int) MetaDataTableIndices.AssemblyRefOS][3]; for (int i = 0; i < count; i++) { int platformID = reader.ReadInt32(); int majorVersion = reader.ReadInt32(); int minorVersion = reader.ReadInt32(); int assemblyRefIndex = ((assemblyRefSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MetaDataAssemblyRef assemblyRef = this.getAssemblyRef(assemblyRefIndex); this.assemblyRefOSArray[i] = new MetaDataAssemblyRefOS(platformID, majorVersion, minorVersion, assemblyRef); } } private void resolveAssemblyRefOSReferences() { // foreach (MetaDataAssemblyRefOS assemblyRefOS in // this.assemblyRefOSArray) { // Console.WriteLine(assemblyRefOS.ToStringLong()); // } } private void initializeFileTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.File]; this.fileArray = new MetaDataFile[count]; this.metaDataTable[(int) MetaDataTableIndices.File] = this.fileArray; for (int i = 0; i < count; i++) { int flags = reader.ReadInt32(); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int hashValueIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); byte[] hashValue = this.getHashValue(hashValueIndex); this.fileArray[i] = new MetaDataFile(flags, name, hashValue); } } private void resolveFileReferences() { // foreach (MetaDataFile file in this.fileArray) { // Console.WriteLine(file.ToStringLong()); // } } private void initializeExportedTypeTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ExportedType]; this.exportedTypeArray = new MetaDataExportedType[count]; this.metaDataTable[(int) MetaDataTableIndices.ExportedType] = this.exportedTypeArray; int implementationSize = this.tableColumnSizes[(int) MetaDataTableIndices.ExportedType][4]; for (int i = 0; i < count; i++) { int flags = reader.ReadInt32(); int typeDefId = reader.ReadInt32(); int typeNameIndex, typeNamespaceIndex; if (this.stringIndexSize == 4) { typeNameIndex = reader.ReadInt32(); typeNamespaceIndex = reader.ReadInt32(); } else { typeNameIndex = reader.ReadUInt16(); typeNamespaceIndex = reader.ReadUInt16(); } String typeName = this.getString(typeNameIndex); String typeNamespace = this.getString(typeNamespaceIndex); int implementationIndex = ((implementationSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.exportedTypeArray[i] = new MetaDataExportedType(flags, typeDefId, typeName, typeNamespace, implementationIndex); } } private void resolveExportedTypeReferences() { foreach (MetaDataExportedType exportedType in this.exportedTypeArray) { exportedType.resolveReferences(this); // Console.WriteLine(exportedType.ToStringLong()); } } private void initializeManifestResourceTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.ManifestResource]; this.manifestResourceArray = new MetaDataManifestResource[count]; this.metaDataTable[(int) MetaDataTableIndices.ManifestResource] = this.manifestResourceArray; int implementationSize = this.tableColumnSizes[(int) MetaDataTableIndices.ManifestResource][3]; for (int i = 0; i < count; i++) { int offset = reader.ReadInt32(); int flags = reader.ReadInt32(); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int implementationIndex = ((implementationSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); byte[] data = ((implementationIndex == 0) ? this.getResourceBytes(offset) : null); // Embedded resource this.manifestResourceArray[i] = new MetaDataManifestResource(offset, flags, name, data, implementationIndex); } } private void resolveManifestResourceReferences() { foreach (MetaDataManifestResource manifestResource in this.manifestResourceArray) { manifestResource.resolveReferences(this); // Console.WriteLine(manifestResource.ToStringLong()); } } private void initializeNestedClassTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.NestedClass]; this.nestedClassArray = new MetaDataNestedClass[count]; this.metaDataTable[(int) MetaDataTableIndices.NestedClass] = this.nestedClassArray; int nestedClassSize = this.tableColumnSizes[(int) MetaDataTableIndices.NestedClass][0]; int enclosingClassSize = this.tableColumnSizes[(int) MetaDataTableIndices.NestedClass][1]; int typeDefCount = this.typeDefArray.Length;; ArrayList[] nestedClassListArray = new ArrayList[typeDefCount+1]; for (int i = 0; i < count; i++) { int nestedClassIndex = ((nestedClassSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int enclosingClassIndex = ((enclosingClassSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); MetaDataTypeDefinition nestedClass = this.getTypeDef(nestedClassIndex); MetaDataTypeDefinition enclosingClass = this.getTypeDef(enclosingClassIndex); ArrayList nestedClassList = nestedClassListArray[enclosingClassIndex]; if (nestedClassList == null) { nestedClassList = new ArrayList(2); nestedClassListArray[enclosingClassIndex] = nestedClassList; } nestedClassList.Add(nestedClass); nestedClass.resolveReferences(enclosingClass); this.nestedClassArray[i] = new MetaDataNestedClass(nestedClass, enclosingClass); } for (int i = 1; i <= typeDefCount; i++) { ArrayList nestedClassList = nestedClassListArray[i]; MetaDataTypeDefinition[] nestedClasses; if (nestedClassList != null) { int nestedCount = nestedClassList.Count; nestedClasses = new MetaDataTypeDefinition[nestedCount]; for (int j = 0; j < nestedCount; j++) { nestedClasses[j] = (MetaDataTypeDefinition) nestedClassList[j]; } } else { nestedClasses = emptyNestedClassArray; } this.getTypeDef(i).resolveReferences(nestedClasses); } } private void resolveNestedClassReferences() { // foreach (MetaDataNestedClass nestedClass in // this.nestedClassArray) { // Console.WriteLine(nestedClass.ToStringLong()); // } } private void initializeGenericParamTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.GenericParam]; //System.Console.WriteLine("Found " + count + " GenericParam entries"); this.genericParamArray = new MetaDataGenericParam[count]; this.metaDataTable[(int) MetaDataTableIndices.GenericParam] = this.genericParamArray; int ownerSize = this.tableColumnSizes[(int) MetaDataTableIndices.GenericParam][2]; int kindSize = this.tableColumnSizes[(int) MetaDataTableIndices.GenericParam][4]; for (int i = 0; i < count; i++) { short number = reader.ReadInt16(); short flags = reader.ReadInt16(); int ownerIndex = ((ownerSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int nameIndex = ((this.stringIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); String name = this.getString(nameIndex); int kind = ((kindSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.genericParamArray[i] = new MetaDataGenericParam(number, flags, ownerIndex, name, kind); } } private void resolveGenericParamReferences() { foreach (MetaDataGenericParam genericParam in this.genericParamArray) { genericParam.resolveReferences(this); } } private void initializeMethodSpecTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.MethodSpec]; //System.Console.WriteLine("Found " + count + " MethodSpec entries"); this.methodSpecArray = new MetaDataMethodSpec[count]; this.metaDataTable[(int) MetaDataTableIndices.MethodSpec] = this.methodSpecArray; int methodSize = this.tableColumnSizes[(int) MetaDataTableIndices.MethodSpec][0]; for (int i = 0; i < count; i++) { int methodIndex = ((methodSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int instantiationIndex = ((this.blobIndexSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); byte[] instantiationValue = this.getHashValue(instantiationIndex); this.methodSpecArray[i] = new MetaDataMethodSpec(methodIndex, instantiationValue); } } private void resolveMethodSpecReferences() { foreach (MetaDataMethodSpec methodSpec in this.methodSpecArray) { methodSpec.resolveReferences(this); // Console.WriteLine(methodSpec.ToStringLong()); } } private void initializeGenericParamConstraintTable(BinaryReader reader) { int count = this.countArray[(int) MetaDataTableIndices.GenericParamConstraint]; //System.Console.WriteLine("Found " + count // + " GenericParamConstraint entries"); this.genericParamConstraintArray = new MetaDataGenericParamConstraint[count]; this.metaDataTable[(int) MetaDataTableIndices.GenericParamConstraint] = this.genericParamConstraintArray; int ownerSize = this.tableColumnSizes [(int) MetaDataTableIndices.GenericParamConstraint][0]; int constraintSize = this.tableColumnSizes [(int) MetaDataTableIndices.GenericParamConstraint][1]; for (int i = 0; i < count; i++) { int ownerIndex = ((ownerSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); int constraintIndex = ((constraintSize == 4) ? reader.ReadInt32() : reader.ReadUInt16()); this.genericParamConstraintArray[i] = new MetaDataGenericParamConstraint(ownerIndex, constraintIndex); } } private void resolveGenericParamConstraintReferences() { foreach (MetaDataGenericParamConstraint constraint in this.genericParamConstraintArray) { constraint.resolveReferences(this); } } private void initializeRelocationTable() { // read in relocation tables int relocationOffset = peLoader.getRelocationOffset(); ArrayList relocations = new ArrayList(); if (relocationOffset > 0) { System.Console.WriteLine("Has relocation table"); // has relocation table fileStream.Seek(relocationOffset, SeekOrigin.Begin); BinaryReader relocReader = new BinaryReader(fileStream); int rva = relocReader.ReadInt32(); while (rva > 0) { int size = relocReader.ReadInt32(); for (int i = 8; i < size; i += 2) { int relocRVA = relocReader.ReadInt16(); if (relocRVA != 0) { if ((relocRVA & 0x3000) != 0x3000) System.Console.WriteLine("Warnging: unknown relocation type"); relocRVA &= 0x0FFF; // the first 4 bits are types relocRVA += rva; relocations.Add(relocRVA); } } rva = relocReader.ReadInt32(); } } else { System.Console.WriteLine("Has no relocation table"); } relocationArray = relocations.ToArray(); } public bool RVAHasRelocation(int rva) { Object[] relocations = this.relocationArray; for (int i = 0; i < relocations.Length; i++) { if (rva == (int) relocations[i]) { return true; } } return false; } private void initializeVtableFixupTable() { // Read the vtableFixup data, if there is any int vtableFixupOffset = peLoader.getVtableFixupOffset(); int vtableFixupSize = peLoader.getVtableFixupSize(); if (vtableFixupOffset > 0 && vtableFixupSize > 0) { fileStream.Seek(vtableFixupOffset, SeekOrigin.Begin); BinaryReader vtableReader = new BinaryReader(fileStream); if (vtableFixupSize % 8 != 0) { System.Console.WriteLine("Warning: fixup size is not multiple of 8 bytes !!"); } // each entry is 8 bytes, first 4 bytes is RVA, // followed by 2 bytes of count, 2 bytes of type int fixupCount = vtableFixupSize / 8; int[] rva = new int[fixupCount]; short[] size = new short[fixupCount]; short[] type = new short[fixupCount]; for (int i = 0; i < fixupCount; i++) { rva[i] = vtableReader.ReadInt32(); size[i] = vtableReader.ReadInt16(); type[i] = vtableReader.ReadInt16(); } this.vtableFixupArray = new MetaDataVtableFixup[fixupCount]; for (int i = 0; i < fixupCount; i++) { int currRVA = rva[i]; short currSize = size[i]; COR_VTABLE currType = (COR_VTABLE) type[i]; // read in the fixup token int offset = peLoader.VaToOffset(currRVA); fileStream.Seek(offset, SeekOrigin.Begin); BinaryReader tokenReader = new BinaryReader(fileStream); MetaDataMethod[] fixupMethods = new MetaDataMethod[currSize]; for (int index = 0; index < currSize; index++) { int token = tokenReader.ReadInt32(); fixupMethods[index] = (MetaDataMethod)this.getObjectFromToken(token); } this.vtableFixupArray[i] = new MetaDataVtableFixup(currRVA, currSize, currType, fixupMethods); } } } public bool HasVtableFixup() { return (this.vtableFixupArray != null); } private void initializeDelayIATTable() { // Read in the dalay IAT table, if there is any int delayIATOffset = peLoader.getDelayIATOffset(); int delayIATSize = peLoader.getDelayIATSize(); if (delayIATOffset > 0 && delayIATSize > 0) { fileStream.Seek(delayIATOffset, SeekOrigin.Begin); BinaryReader delayIATReader = new BinaryReader(fileStream); int characteristics = delayIATReader.ReadInt32(); int addressOfDllName = peLoader.VaToOffset(delayIATReader.ReadInt32()); int addressOfHModule = delayIATReader.ReadInt32(); int rvaOfIAT = peLoader.VaToOffset(delayIATReader.ReadInt32()); int nameTable = peLoader.VaToOffset(delayIATReader.ReadInt32()); // read in dll name string dllName = peLoader.readString(addressOfDllName); // read in import address table fileStream.Seek(rvaOfIAT, SeekOrigin.Begin); BinaryReader IATReader = new BinaryReader(fileStream); int importAddress = IATReader.ReadInt32(); int count = 0; ArrayList imports = new ArrayList(); while (importAddress != 0) { count++; imports.Add(importAddress); importAddress = IATReader.ReadInt32(); } object[] importArray = imports.ToArray(); // read in the names fileStream.Seek(nameTable, SeekOrigin.Begin); BinaryReader nameAddrReader = new BinaryReader(fileStream); int[] nameAddress = new int[count]; for (int i = 0; i < count; i++) { int nameAddr = nameAddrReader.ReadInt32(); nameAddress[i] = peLoader.VaToOffset(nameAddr + 2); } String[] names = new String[count]; for (int i = 0; i < count; i++) { names[i] = peLoader.readString(nameAddress[i]); } this.delayImportTable = new MetaDataDelayImportTable(dllName, importArray, names); System.Console.WriteLine(this.delayImportTable.ToString()); } } // State private readonly PELoader peLoader; private readonly Stream fileStream; private readonly int metaDataOffset; private readonly StorageStream dataStream; private readonly StorageStream stringPoolStream; private readonly StorageStream userBlobPoolStream; private readonly StorageStream guidPoolStream; private readonly StorageStream blobPoolStream; // Schema fields (for logical tables) private int reserved; private byte majorVersion; private byte minorVersion; private byte heapBits; private byte rowId; private long maskValid; private long maskSorted; private int[] countArray = new int[(int) MetaDataTableIndices.Count]; private byte[][] tableColumnSizes = new byte[(int) MetaDataTableIndices.Count][]; private byte[][] tableColumnOffsets = new byte[(int) MetaDataTableIndices.Count][]; private byte[] tableRowSizes = new byte[(int) MetaDataTableIndices.Count]; private int extraData; private byte stringIndexSize; private byte guidIndexSize; private byte blobIndexSize; private readonly byte[] stringStreamBuffer; private readonly byte[] blobStreamBuffer; private readonly byte[] userStringStreamBuffer; private readonly byte[] resourceBuffer; private readonly Guid[] guidArray; private MetaDataObject[][] metaDataTable; private MetaDataModule[] moduleArray; private MetaDataTypeReference[] typeRefArray; private MetaDataTypeDefinition[] typeDefArray; private MetaDataFieldPtr[] fieldPtrArray; private MetaDataField[] fieldArray; private MetaDataMethodPtr[] methodPtrArray; private MetaDataMethod[] methodArray; private MetaDataParamPtr[] paramPtrArray; private MetaDataParam[] paramArray; private MetaDataInterfaceImpl[] interfaceImplArray; private MetaDataMemberRef[] memberRefArray; private MetaDataConstant[] constantArray; private MetaDataCustomAttribute[] customAttributeArray; private MetaDataFieldMarshal[] fieldMarshalArray; private MetaDataDeclSecurity[] declSecurityArray; private MetaDataClassLayout[] classLayoutArray; private MetaDataFieldLayout[] fieldLayoutArray; private MetaDataStandAloneSig[] standAloneSigArray; private MetaDataEventMap[] eventMapArray; private MetaDataEventPtr[] eventPtrArray; private MetaDataEvent[] eventArray; private MetaDataPropertyMap[] propertyMapArray; private MetaDataPropertyPtr[] propertyPtrArray; private MetaDataProperty[] propertyArray; private MetaDataMethodSemantics[] methodSemanticsArray; private MetaDataMethodImpl[] methodImplArray; private MetaDataModuleRef[] moduleRefArray; private MetaDataTypeSpec[] typeSpecArray; private MetaDataImplMap[] implMapArray; private MetaDataFieldRVA[] fieldRVAArray; private MetaDataAssembly[] assemblyArray; private MetaDataAssemblyProcessor[] assemblyProcessorArray; private MetaDataAssemblyOS[] assemblyOSArray; private MetaDataAssemblyRef[] assemblyRefArray; private MetaDataAssemblyRefProcessor[] assemblyRefProcessorArray; private MetaDataAssemblyRefOS[] assemblyRefOSArray; private MetaDataFile[] fileArray; private MetaDataExportedType[] exportedTypeArray; private MetaDataManifestResource[] manifestResourceArray; private MetaDataNestedClass[] nestedClassArray; private MetaDataGenericParam[] genericParamArray; private MetaDataMethodSpec[] methodSpecArray; private MetaDataGenericParamConstraint[] genericParamConstraintArray; private Object[] relocationArray; private MetaDataVtableFixup[] vtableFixupArray; private MetaDataDelayImportTable delayImportTable; private readonly static MetaDataTypeDefinition[] emptyNestedClassArray = new MetaDataTypeDefinition[0]; private readonly static MetaDataParam[] emptyParamArray = new MetaDataParam[0]; private readonly static MetaDataField[] emptyFieldArray = new MetaDataField[0]; private readonly static MetaDataMethod[] emptyMethodArray = new MetaDataMethod[0]; private readonly static MetaDataObject[] emptyInterfaceArray = new MetaDataObject[0]; private const int METAMODEL_MAJOR_VER = 1; private const int METAMODEL_MINOR_VER_A = 0; private const int METAMODEL_MINOR_VER_B = 1; private const int HEAPBITS_MASK_STRINGS = 0x01; private const int HEAPBITS_MASK_GUID = 0x02; private const int HEAPBITS_MASK_BLOB = 0x04; private const int HEAPBITS_MASK_PADDING_BIT = 0x08; private const int HEAPBITS_MASK_DELTA_ONLY = 0x20; private const int HEAPBITS_MASK_EXTRA_DATA = 0x40; private const int HEAPBITS_MASK_HAS_DELETE = 0x80; internal static readonly System.Text.UTF8Encoding stringEncoding = new System.Text.UTF8Encoding(); private static readonly byte[][] TableColumnKinds = new byte[(int) MetaDataTableIndices.Count][] { // rModuleCols new byte[] { (byte) (byte) ColumnKindId.UShort, (byte) ColumnKindId.String, (byte) ColumnKindId.Guid, (byte) ColumnKindId.Guid, (byte) ColumnKindId.Guid }, // rTypeRefCols new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.ResolutionScope, (byte) ColumnKindId.String, (byte) ColumnKindId.String }, // rTypeDefCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.String, (byte) ColumnKindId.String, (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef, (byte) MetaDataTableIndices.Field, (byte) MetaDataTableIndices.Method }, // rFieldPtrCols new byte[] { (byte) MetaDataTableIndices.Field }, // rFieldCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.String, (byte) ColumnKindId.Blob }, // rMethodPtrCols new byte[] { (byte) MetaDataTableIndices.Method }, // rMethodCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.String, (byte) ColumnKindId.Blob, (byte) MetaDataTableIndices.Param }, // rParamPtrCols new byte[] { (byte) MetaDataTableIndices.Param }, // rParamCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.String }, // rInterfaceImplCols new byte[] { (byte) MetaDataTableIndices.TypeDef, (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef }, // rMemberRefCols new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.MemberRefParent, (byte) ColumnKindId.String, (byte) ColumnKindId.Blob }, // rConstantCols new byte[] { (byte) ColumnKindId.Byte, (byte) ColumnKindId.CodedToken + (byte) CodeToken.HasConstant, (byte) ColumnKindId.Blob }, // rCustomAttributeCols new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.HasCustomAttribute, (byte) ColumnKindId.CodedToken + (byte) CodeToken.CustomAttributeType, (byte) ColumnKindId.Blob }, // rFieldMarshalCols new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.HasFieldMarshal, (byte) ColumnKindId.Blob }, // rDeclSecurityCols new byte[] { (byte) ColumnKindId.Short, (byte) ColumnKindId.CodedToken + (byte) CodeToken.HasDeclSecurity, (byte) ColumnKindId.Blob }, // rClassLayoutCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.ULong, (byte) MetaDataTableIndices.TypeDef }, // rFieldLayoutCols new byte[] { (byte) ColumnKindId.ULong, (byte) MetaDataTableIndices.Field }, // rStandAloneSigCols new byte[] { (byte) ColumnKindId.Blob }, // rEventMapCols new byte[] { (byte) MetaDataTableIndices.TypeDef, (byte) MetaDataTableIndices.Event }, // rEventPtrCols new byte[] { (byte) MetaDataTableIndices.Event }, // rEventCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.String, (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef }, // rPropertyMapCols new byte[] { (byte) MetaDataTableIndices.TypeDef, (byte) MetaDataTableIndices.Property }, // rPropertyPtrCols new byte[] { (byte) MetaDataTableIndices.Property }, // rPropertyCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.String, (byte) ColumnKindId.Blob }, // rMethodSemanticsCols new byte[] { (byte) ColumnKindId.UShort, (byte) MetaDataTableIndices.Method, (byte) ColumnKindId.CodedToken + (byte) CodeToken.HasSemantic }, // rMethodImplCols new byte[] { (byte) MetaDataTableIndices.TypeDef, (byte) ColumnKindId.CodedToken + (byte) CodeToken.MethodDefOrRef, (byte) ColumnKindId.CodedToken + (byte) CodeToken.MethodDefOrRef }, // rModuleRefCols new byte[] { (byte) ColumnKindId.String }, // rTypeSpecCols new byte[] { (byte) ColumnKindId.Blob }, // rImplMapCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.CodedToken + (byte) CodeToken.MemberForwarded, (byte) ColumnKindId.String, (byte) MetaDataTableIndices.ModuleRef }, // rFieldRVACols new byte[] { (byte) ColumnKindId.ULong, (byte) MetaDataTableIndices.Field }, // rENCLogCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.ULong }, // rENCMapCols new byte[] { (byte) ColumnKindId.ULong }, // rAssemblyCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.ULong, (byte) ColumnKindId.Blob, (byte) ColumnKindId.String, (byte) ColumnKindId.String }, // rAssemblyProcessorCols new byte[] { (byte) ColumnKindId.ULong }, // rAssemblyOSCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.ULong, (byte) ColumnKindId.ULong }, // rAssemblyRefCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.ULong, (byte) ColumnKindId.Blob, (byte) ColumnKindId.String, (byte) ColumnKindId.String, (byte) ColumnKindId.Blob }, // rAssemblyRefProcessorCols new byte[] { (byte) ColumnKindId.ULong, (byte) MetaDataTableIndices.AssemblyRef }, // rAssemblyRefOSCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.ULong, (byte) ColumnKindId.ULong, (byte) MetaDataTableIndices.AssemblyRef }, // rFileCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.String, (byte) ColumnKindId.Blob }, // rExportedTypeCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.ULong, (byte) ColumnKindId.String, (byte) ColumnKindId.String, (byte) ColumnKindId.CodedToken + (byte) CodeToken.Implementation }, // rManifestResourceCols new byte[] { (byte) ColumnKindId.ULong, (byte) ColumnKindId.ULong, (byte) ColumnKindId.String, (byte) ColumnKindId.CodedToken + (byte) CodeToken.Implementation }, // rNestedClassCols new byte[] { (byte) MetaDataTableIndices.TypeDef, (byte) MetaDataTableIndices.TypeDef }, // rGenericParamCols new byte[] { (byte) ColumnKindId.UShort, (byte) ColumnKindId.UShort, (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeOrMethodDef, (byte) ColumnKindId.String, (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef, // (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef }, // rMethodSpecCols new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.MethodDefOrRef, (byte) ColumnKindId.Blob }, // rGenericParamConstraintCols new byte[] { (byte) ColumnKindId.CodedToken + (byte) CodeToken.GenericParam, (byte) ColumnKindId.CodedToken + (byte) CodeToken.TypeDefOrRef }, }; // These are for informational use only! Not used anywhere. private static readonly String[][] TableColumnNames = new String[(int) MetaDataTableIndices.Count][] { // rModuleColNames new String[] { "Generation", "Name", "Mvid", "EncId", "EncBaseId" }, // rTypeRefColNames new String[] { "ResolutionScope", "Name", "Namespace" }, // rTypeDefColNames new String[] { "Flags", "Name", "Namespace", "Extends", "FieldList", "MethodList" }, // rFieldPtrColNames new String[] { "Field" }, // rFieldColNames new String[] { "Flags", "Name", "Signature" }, // rMethodPtrColNames new String[] { "Method" }, // rMethodColNames new String[] { "RVA", "ImplFlags", "Flags", "Name", "Signature", "ParamList" }, // rParamPtrColNames new String[] { "Param" }, // rParamColNames new String[] { "Flags", "Sequence", "Name" }, // rInterfaceImplColNames new String[] { "Class", "Interface" }, // rMemberRefColNames new String[] { "Class", "Name", "Signature" }, // rConstantColNames new String[] { "Type", "Parent", "Value" }, // rCustomAttributeColNames new String[] { "Parent", "Type", "Value" }, // rFieldMarshalColNames new String[] { "Parent", "NativeType" }, // rDeclSecurityColNames new String[] { "Action", "Parent", "PermissionSet" }, // rClassLayoutColNames new String[] { "PackingSize", "ClassSize", "Parent" }, // rFieldLayoutColNames new String[] { "OffSet", "Field" }, // rStandAloneSigColNames new String[] { "Signature" }, // rEventMapColNames new String[] { "Parent", "EventList" }, // rEventPtrColNames new String[] { "Event" }, // rEventColNames new String[] { "EventFlags", "Name", "EventType" }, // rPropertyMapColNames new String[] { "Parent", "PropertyList" }, // rPropertyPtrColNames new String[] { "Property" }, // rPropertyColNames new String[] { "PropFlags", "Name", "Type" }, // rMethodSemanticsColNames new String[] { "Semantic", "Method", "Association" }, // rMethodImplColNames new String[] { "Class", "MethodBody", "MethodDeclaration" }, // rModuleRefColNames new String[] { "Name" }, // rTypeSpecColNames new String[] { "Signature" }, // rImplMapColNames new String[] { "MappingFlags", "MemberForwarded", "ImportName", "ImportScope" }, // rFieldRVAColNames new String[] { "RVA", "Field" }, // rENCLogColNames new String[] { "Token", "FuncCode" }, // rENCMapColNames new String[] { "Token" }, // rAssemblyColNames new String[] { "HashAlgId", "MajorVersion", "MinorVersion", "BuildNumber", "RevisionNumber", "Flags", "PublicKey", "Name", "Locale" }, // rAssemblyProcessorColNames new String[] { "Processor" }, // rAssemblyOSColNames new String[] { "OSPlatformId", "OSMajorVersion", "OSMinorVersion" }, // rAssemblyRefColNames new String[] { "MajorVersion", "MinorVersion", "BuildNumber", "RevisionNumber", "Flags", "PublicKeyOrToken", "Name", "Locale", "HashValue" }, // rAssemblyRefProcessorColNames new String[] { "Processor", "AssemblyRef" }, // rAssemblyRefOSColNames new String[] { "OSPlatformId", "OSMajorVersion", "OSMinorVersion", "AssemblyRef" }, // rFileColNames new String[] { "Flags", "Name", "HashValue" }, // rExportedTypeColNames new String[] { "Flags", "TypeDefId", "TypeName", "TypeNamespace", "Implementation" }, // rManifestResourceColNames new String[] { "Offset", "Flags", "Name", "Implementation" }, // rNestedClassColNames new String[] { "NestedClass", "EnclosingClass" }, // rGenericParamColNames new String[] { "Number", "Flags", "Owner", "Name", "Kind" },//, "DeprecatedConstraint" }, // rMethodSpecNames new String[] { "Method", "Instantiation" }, // rGenericParamConstraintColNames new String[] { "Owner", "Constraint" }, }; private static readonly int[] BitsForCountArray = new int[] { 0,1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }; private static readonly int[] MaskForCountArray = new int[] { 0,1,1,3,3,7,7,7,7,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x1f,0x1f,0x1f, 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f }; private static readonly TokenType[][] CodeTokenTypeLists = new TokenType[(int) CodeToken.Count][] { // TypeDefOrRef new TokenType[] { TokenType.TypeDef, TokenType.TypeRef, TokenType.TypeSpec }, // HasConstant new TokenType[] { TokenType.FieldDef, TokenType.ParamDef, TokenType.Property }, // HasCustomAttribute new TokenType[] { TokenType.MethodDef, TokenType.FieldDef, TokenType.TypeRef, TokenType.TypeDef, TokenType.ParamDef, TokenType.InterfaceImpl, TokenType.MemberRef, TokenType.Module, TokenType.Permission, TokenType.Property, TokenType.Event, TokenType.Signature, TokenType.ModuleRef, TokenType.TypeSpec, TokenType.Assembly, TokenType.AssemblyRef, TokenType.File, TokenType.ExportedType, TokenType.ManifestResource}, // HasFieldMarshal new TokenType[] { TokenType.FieldDef, TokenType.ParamDef }, // HasDeclSecurity new TokenType[] { TokenType.TypeDef, TokenType.MethodDef, TokenType.Assembly }, // MemberRefParent new TokenType[] { TokenType.TypeDef, TokenType.TypeRef, TokenType.ModuleRef, TokenType.MethodDef, TokenType.TypeSpec }, // HasSemantic new TokenType[] { TokenType.Event, TokenType.Property }, // MethodDefOrRef new TokenType[] { TokenType.MethodDef, TokenType.MemberRef }, // MemberForwarded new TokenType[] { TokenType.FieldDef, TokenType.MethodDef }, // Implementation new TokenType[] { TokenType.File, TokenType.AssemblyRef, TokenType.ExportedType }, // CustomAttributeType new TokenType[] { TokenType.TypeRef, // as per 3705: 0 TokenType.TypeDef, // as per 3705: 0 TokenType.MethodDef, TokenType.MemberRef, TokenType.String }, // as per 3705: 0 // ResolutionScope new TokenType[] { TokenType.Module, TokenType.ModuleRef, TokenType.AssemblyRef, TokenType.TypeRef }, // TypeOrMethodDef new TokenType[] { TokenType.TypeDef, TokenType.MethodDef }, // GenericParam new TokenType[] { TokenType.GenericParam }, }; // static MetaDataLoader() { // if ((int) TokenType.Module >> 24 != (int) MetaDataTableIndices.Module || // (int) TokenType.TypeRef >> 24 != (int) MetaDataTableIndices.TypeRef || // (int) TokenType.TypeDef >> 24 != (int) MetaDataTableIndices.TypeDef || // (int) TokenType.FieldDef >> 24 != (int) MetaDataTableIndices.Field || // (int) TokenType.MethodDef >> 24 != (int) MetaDataTableIndices.Method || // (int) TokenType.ParamDef >> 24 != (int) MetaDataTableIndices.Param || // (int) TokenType.InterfaceImpl >> 24 != (int) MetaDataTableIndices.InterfaceImpl || // (int) TokenType.MemberRef >> 24 != (int) MetaDataTableIndices.MemberRef || // (int) TokenType.CustomAttribute >> 24 != (int) MetaDataTableIndices.CustomAttribute || // (int) TokenType.Permission >> 24 != (int) MetaDataTableIndices.DeclSecurity || // (int) TokenType.Signature >> 24 != (int) MetaDataTableIndices.StandAloneSig || // (int) TokenType.Event >> 24 != (int) MetaDataTableIndices.Event || // (int) TokenType.Property >> 24 != (int) MetaDataTableIndices.Property || // (int) TokenType.ModuleRef >> 24 != (int) MetaDataTableIndices.ModuleRef || // (int) TokenType.TypeSpec >> 24 != (int) MetaDataTableIndices.TypeSpec || // (int) TokenType.Assembly >> 24 != (int) MetaDataTableIndices.Assembly || // (int) TokenType.AssemblyRef >> 24 != (int) MetaDataTableIndices.AssemblyRef || // (int) TokenType.File >> 24 != (int) MetaDataTableIndices.File || // (int) TokenType.ExportedType >> 24 != (int) MetaDataTableIndices.ExportedType || // (int) TokenType.ManifestResource >> 24 != (int) MetaDataTableIndices.ManifestResource) { // throw new IllegalMetaDataFormatException("TBL invariant broken"); // } // for (int i = 0; i < (int) MetaDataTableIndices.Count; i++) { // if (TableColumnKinds[i].Length != TableColumnNames[i].Length) { // throw new IllegalMetaDataFormatException("Column spec mismatch at "+i); // } // } // } protected enum MetaDataFormat: byte { Invalid, ReadOnly, ReadWrite, ICR } protected enum MetaDataTableIndices: byte { Module, TypeRef, TypeDef, FieldPtr, Field, MethodPtr, Method, ParamPtr, Param, InterfaceImpl, MemberRef, Constant, CustomAttribute, FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig, EventMap, EventPtr, Event, PropertyMap, PropertyPtr, Property, MethodSemantics, MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, ENCLog, ENCMap, Assembly, AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor, AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass, GenericParam, MethodSpec, GenericParamConstraint, Count } internal enum TokenType: int { Module = 0x00000000, TypeRef = 0x01000000, TypeDef = 0x02000000, FieldDef = 0x04000000, MethodDef = 0x06000000, ParamDef = 0x08000000, InterfaceImpl = 0x09000000, MemberRef = 0x0a000000, CustomAttribute = 0x0c000000, Permission = 0x0e000000, Signature = 0x11000000, Event = 0x14000000, Property = 0x17000000, ModuleRef = 0x1a000000, TypeSpec = 0x1b000000, Assembly = 0x20000000, AssemblyRef = 0x23000000, File = 0x26000000, ExportedType = 0x27000000, ManifestResource = 0x28000000, GenericParam = 0x2a000000, String = 0x70000000, Name = 0x71000000, BaseType = 0x72000000 }; private enum ColumnKindId { RowIdMax = 63, CodedToken = 64, CodedTokenMax = 95, Short = 96, UShort = 97, Long = 98, ULong = 99, Byte = 100, String = 101, Guid = 102, Blob = 103 }; private enum CodeToken: byte { TypeDefOrRef, HasConstant, HasCustomAttribute, HasFieldMarshal, HasDeclSecurity, MemberRefParent, HasSemantic, MethodDefOrRef, MemberForwarded, Implementation, CustomAttributeType, ResolutionScope, TypeOrMethodDef, GenericParam, Count }; private enum SymTag { SymTagEnd = -1, SymTagFunction, SymTagLocal }; // Nested Classes private class StorageSignature { // Constructor Methods internal StorageSignature(Stream stream): this(new BinaryReader(stream)) { // Do nothing extra } internal StorageSignature(BinaryReader reader) { this.signature = reader.ReadInt32(); this.majorVersion = reader.ReadInt16(); this.minorVersion = reader.ReadInt16(); this.extraData = reader.ReadInt32(); int length = reader.ReadInt32(); byte[] bytes = new byte[length]; reader.Read(bytes, 0, length); char[] chars = new char[length]; for (int i = 0; i < length; i++) { chars[i] = (char) bytes[i]; } this.versionString = new String(chars); if (this.signature != StorageSignature.STORAGE_MAGIC_SIG) { throw new IllegalMetaDataFormatException("Don't know signature "+this.signature.ToString("x8")); } if (this.majorVersion != StorageSignature.FILE_MAJOR_VERSION || this.minorVersion != StorageSignature.FILE_MINOR_VERSION) { throw new IllegalMetaDataFormatException("Unknown version"); } } // State internal readonly int signature; internal readonly short majorVersion; internal readonly short minorVersion; internal readonly int extraData; internal readonly String versionString; private const int STORAGE_MAGIC_SIG = 0x424A5342; private const int FILE_MAJOR_VERSION = 1; private const int FILE_MINOR_VERSION = 1; } private class StorageHeader { // Constructor Methods internal StorageHeader(Stream stream): this(new BinaryReader(stream)) { } internal StorageHeader(BinaryReader reader) { this.flags = reader.ReadByte(); this.pad = reader.ReadByte(); this.streamCount = reader.ReadInt16(); if ((this.flags & STGHDR_EXTRADATA) != 0) { int count = reader.ReadInt32(); reader.ReadBytes(count); } } // State internal Byte flags; internal Byte pad; internal short streamCount; internal const Byte STGHDR_EXTRADATA = 0x01; } private class StorageStream { // Constructor Methods internal StorageStream(Stream stream): this(new BinaryReader(stream)) { } internal StorageStream(BinaryReader reader) { this.offset = reader.ReadInt32(); this.size = reader.ReadInt32(); byte[] bytes = new byte[4]; int startIndex = 0; bool foundEnd = false; while (!foundEnd) { int count = reader.Read(bytes, startIndex, 4); int limit = startIndex + count; for (int i = startIndex; i < limit; i++) { if (bytes[i] == 0) { foundEnd = true; char[] chars = new char[i]; for (int j = 0; j < i; j++) { chars[j] = (char) bytes[j]; } this.name = new String(chars); break; } } startIndex = limit; if (startIndex == bytes.Length) { byte[] newBytes = new byte[2*startIndex]; for (int i = 0; i < startIndex; i++) { newBytes[i] = bytes[i]; } bytes = newBytes; } } while (startIndex % 4 != 0) { startIndex += reader.Read(bytes, 0, startIndex % 4); } } // Output Methods public override String ToString() { return "StorageStream("+this.name+","+this.offset+","+this.size+")"; } // State internal int offset; internal int size; internal String name; internal const String COMPRESSED_MODEL = "#~"; internal const String ENC_MODEL = "#-"; internal const String SCHEMA = "#Schema"; internal const String STRING_POOL = "#Strings"; internal const String BLOB_POOL = "#Blob"; internal const String USER_BLOB_POOL = "#US"; internal const String VARIANT_POOL = "#Variants"; internal const String GUID_POOL = "#GUID"; } private class DebugEntry { // Constructor Methods internal DebugEntry(Stream stream): this(new BinaryReader(stream)) { } internal DebugEntry(BinaryReader reader) { this.characteristics = reader.ReadInt32(); this.timeDateStamp = reader.ReadInt32(); this.majorVersion = reader.ReadInt16(); this.minorVersion = reader.ReadInt16(); this.formatType = reader.ReadInt32(); this.sizeOfData = reader.ReadInt32(); this.addressOfRawData = reader.ReadInt32(); this.pointerToRawData = reader.ReadInt32(); } // State internal int characteristics; internal int timeDateStamp; internal short majorVersion; internal short minorVersion; internal int formatType; internal int sizeOfData; internal int addressOfRawData; internal int pointerToRawData; } internal class IllegalMetaDataFormatException: Exception { internal IllegalMetaDataFormatException(String reason): base(reason) { } } } }