static int CountCilInstructions(MemoryReader memReader) { int count = 0; while (memReader.NotEndOfBytes) { count++; OperationCode cilOpCode = memReader.ReadOpcode(); switch (cilOpCode) { case OperationCode.Ldarg_S: case OperationCode.Ldarga_S: case OperationCode.Starg_S: case OperationCode.Ldloc_S: case OperationCode.Ldloca_S: case OperationCode.Stloc_S: case OperationCode.Ldc_I4_S: case OperationCode.Br_S: case OperationCode.Brfalse_S: case OperationCode.Brtrue_S: case OperationCode.Beq_S: case OperationCode.Bge_S: case OperationCode.Bgt_S: case OperationCode.Ble_S: case OperationCode.Blt_S: case OperationCode.Bne_Un_S: case OperationCode.Bge_Un_S: case OperationCode.Bgt_Un_S: case OperationCode.Ble_Un_S: case OperationCode.Blt_Un_S: case OperationCode.Leave_S: case OperationCode.Unaligned_: case OperationCode.No_: memReader.SkipBytes(1); break; case OperationCode.Ldarg: case OperationCode.Ldarga: case OperationCode.Starg: case OperationCode.Ldloc: case OperationCode.Ldloca: case OperationCode.Stloc: memReader.SkipBytes(2); break; case OperationCode.Ldc_I4: case OperationCode.Jmp: case OperationCode.Call: case OperationCode.Calli: case OperationCode.Br: case OperationCode.Brfalse: case OperationCode.Brtrue: case OperationCode.Beq: case OperationCode.Bge: case OperationCode.Bgt: case OperationCode.Ble: case OperationCode.Blt: case OperationCode.Bne_Un: case OperationCode.Bge_Un: case OperationCode.Bgt_Un: case OperationCode.Ble_Un: case OperationCode.Blt_Un: case OperationCode.Callvirt: case OperationCode.Cpobj: case OperationCode.Ldobj: case OperationCode.Ldstr: case OperationCode.Newobj: case OperationCode.Castclass: case OperationCode.Isinst: case OperationCode.Unbox: case OperationCode.Ldfld: case OperationCode.Ldflda: case OperationCode.Stfld: case OperationCode.Ldsfld: case OperationCode.Ldsflda: case OperationCode.Stsfld: case OperationCode.Stobj: case OperationCode.Box: case OperationCode.Newarr: case OperationCode.Ldelema: case OperationCode.Ldelem: case OperationCode.Stelem: case OperationCode.Unbox_Any: case OperationCode.Refanyval: case OperationCode.Mkrefany: case OperationCode.Ldtoken: case OperationCode.Leave: case OperationCode.Ldftn: case OperationCode.Ldvirtftn: case OperationCode.Initobj: case OperationCode.Constrained_: case OperationCode.Sizeof: case OperationCode.Ldc_R4: memReader.SkipBytes(4); break; case OperationCode.Ldc_I8: case OperationCode.Ldc_R8: memReader.SkipBytes(8); break; case OperationCode.Switch: int numTargets = (int)memReader.ReadUInt32(); memReader.SkipBytes(4*numTargets); break; default: break; } } memReader.SeekOffset(0); return count; }
bool ReadMetadataHeader( ref MemoryReader memReader ) //^ requires this.ReaderState >= ReaderState.PEFile; { if (memReader.RemainingBytes < COR20Constants.MinimumSizeofMetadataHeader) { this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, 0, MetadataReaderErrorKind.MetadataHeaderTooSmall); return false; } this.MetadataHeader.Signature = memReader.ReadUInt32(); if (this.MetadataHeader.Signature != COR20Constants.COR20MetadataSignature) { this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, memReader.Offset - sizeof(uint), MetadataReaderErrorKind.MetadataSignature); return false; } this.MetadataHeader.MajorVersion = memReader.ReadUInt16(); this.MetadataHeader.MinorVersion = memReader.ReadUInt16(); this.MetadataHeader.ExtraData = memReader.ReadUInt32(); this.MetadataHeader.VersionStringSize = memReader.ReadInt32(); if (memReader.RemainingBytes < this.MetadataHeader.VersionStringSize) { this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, memReader.Offset, MetadataReaderErrorKind.NotEnoughSpaceForVersionString); return false; } int numberOfBytesRead; this.MetadataHeader.VersionString = memReader.PeekUTF8NullTerminated(0, out numberOfBytesRead); memReader.SkipBytes(this.MetadataHeader.VersionStringSize); return true; }
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 ); }
private PEFileDebugInformation ReadDebugInformationLocationFromDebugTableDirectoryData() { if (this.OptionalHeaderDirectoryEntries.DebugTableDirectory.Size != 0x1c) return new PEFileDebugInformation(); var debugDirectoryReader = new MemoryReader(this.DirectoryToMemoryBlock(this.OptionalHeaderDirectoryEntries.DebugTableDirectory)); PeDebugDirectory debugDir = new PeDebugDirectory(); debugDir.Characteristics = debugDirectoryReader.ReadUInt32(); debugDir.TimeDateStamp = debugDirectoryReader.ReadUInt32(); debugDir.MajorVersion = debugDirectoryReader.ReadUInt16(); debugDir.MinorVersion = debugDirectoryReader.ReadUInt16(); debugDir.Type = debugDirectoryReader.ReadUInt32(); debugDir.SizeOfData = debugDirectoryReader.ReadUInt32(); debugDir.AddressOfRawData = debugDirectoryReader.ReadUInt32(); debugDir.PointerToRawData = debugDirectoryReader.ReadUInt32(); if (debugDir.SizeOfData == 0) return new PEFileDebugInformation(); var dataBlock = new MemoryBlock(this.BinaryDocumentMemoryBlock.Pointer + debugDir.PointerToRawData, debugDir.SizeOfData); var ptrToDebugInfo = this.BinaryDocumentMemoryBlock.Pointer + debugDir.PointerToRawData; var ptrToDebugInfoEnd = this.BinaryDocumentMemoryBlock.Pointer + debugDir.PointerToRawData + debugDir.SizeOfData; if (ptrToDebugInfo >= this.BinaryDocumentMemoryBlock.Pointer + this.BinaryDocumentMemoryBlock.Length - 28) { //TODO: error return new PEFileDebugInformation(); } if (ptrToDebugInfoEnd > this.BinaryDocumentMemoryBlock.Pointer + this.BinaryDocumentMemoryBlock.Length) { //TODO: error return new PEFileDebugInformation(); } var debugDataReader = new MemoryReader(dataBlock); var magic = debugDataReader.ReadUInt32(); if (magic != 0x53445352) { //RSDS in little endian format //TODO: error return new PEFileDebugInformation(); } var guid = debugDataReader.PeekGuid(0); debugDataReader.SkipBytes(16); UInt32 age = debugDataReader.ReadUInt32(); string fileName = debugDataReader.ReadASCIINullTerminated(); var guidHex = guid.ToString("N"); string ageHex = age.ToString("X"); string version = guidHex + ageHex; PEFileDebugInformation information = new PEFileDebugInformation(); information.Signature = guid; information.Age = age; information.PdbVersion = version; information.PdbFileName = fileName; return information; }