internal MethodIL/*?*/ GetMethodIL( uint methodDefRowId ) { MethodRow methodRow = this.MethodTable[methodDefRowId]; if ( (methodRow.ImplFlags & MethodImplFlags.CodeTypeMask) != MethodImplFlags.ILCodeType || methodRow.RVA == 0 ) { return null; } MemoryBlock memBlock = this.RVAToMemoryBlock(methodRow.RVA); // Error need to check if the Memory Block is empty. This is calse for all the calls... MemoryReader memReader = new MemoryReader(memBlock); byte headByte = memReader.ReadByte(); if ((headByte & CILMethodFlags.ILFormatMask) == CILMethodFlags.ILTinyFormat) { int size = headByte >> CILMethodFlags.ILTinyFormatSizeShift; return new MethodIL( true, 8, 0x00000000, memReader.GetMemoryBlockAt(0, size), null ); } else if ((headByte & CILMethodFlags.ILFormatMask) != CILMethodFlags.ILFatFormat) { // PEFileFormat Error... return null; } // FatILFormat byte headByte2 = memReader.ReadByte(); if ((headByte2 >> CILMethodFlags.ILFatFormatHeaderSizeShift) != CILMethodFlags.ILFatFormatHeaderSize) { // PEFile Format Error... return null; } bool localVarInited = (headByte & CILMethodFlags.ILInitLocals) == CILMethodFlags.ILInitLocals; bool moreSectsPresent = (headByte & CILMethodFlags.ILMoreSects) == CILMethodFlags.ILMoreSects; ushort maxStack = memReader.ReadUInt16(); int codeSize = memReader.ReadInt32(); uint localSignatureToken = memReader.ReadUInt32(); MemoryBlock ilCodeMemBlock = memReader.GetMemoryBlockAt(0, codeSize); SEHTableEntry[]/*?*/ sehTableEntries = null; if (moreSectsPresent) { memReader.SkipBytes(codeSize); memReader.Align(4); byte sectHeader = memReader.ReadByte(); if ((sectHeader & CILMethodFlags.SectEHTable) != CILMethodFlags.SectEHTable) { // PEFile Format Error... return null; } bool sectFatFormat = (sectHeader & CILMethodFlags.SectFatFormat) == CILMethodFlags.SectFatFormat; int dataSize = memReader.ReadByte(); if (sectFatFormat) { dataSize += (int)memReader.ReadUInt16() << 8; sehTableEntries = PEFileReader.GetFatSEHEntries(memReader, dataSize / 24); } else { memReader.SkipBytes(2); //skip over reserved field sehTableEntries = PEFileReader.GetSmallSEHEntries(memReader, dataSize / 12); } } return new MethodIL( localVarInited, maxStack, localSignatureToken, ilCodeMemBlock, sehTableEntries ); }
bool ReadStreamHeaders( ref MemoryReader memReader ) //^ requires this.ReaderState >= ReaderState.PEFile; { int numberOfStreams = this.StorageHeader.NumberOfStreams; this.StreamHeaders = new StreamHeader[numberOfStreams]; StreamHeader[] streamHeaders = this.StreamHeaders; for (int i = 0; i < numberOfStreams; ++i) { if (memReader.RemainingBytes < COR20Constants.MinimumSizeofStreamHeader) { this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, memReader.Offset, MetadataReaderErrorKind.StreamHeaderTooSmall); return false; } streamHeaders[i].Offset = memReader.ReadUInt32(); streamHeaders[i].Size = memReader.ReadInt32(); // Review: Oh well there is no way i can test if we will read correctly. However we can check it after reading and aligning... streamHeaders[i].Name = memReader.ReadASCIINullTerminated(); memReader.Align(4); if (memReader.RemainingBytes < 0) { this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, memReader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForStreamHeaderName); return false; } } return true; }