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 ReadPEFileLevelData() //^ requires this.ReaderState >= ReaderState.Initialized; { MemoryReader memReader = new MemoryReader(this.BinaryDocumentMemoryBlock.Pointer, this.BinaryDocumentMemoryBlock.Length); if (memReader.RemainingBytes < PEFileConstants.BasicPEHeaderSize) { this.ErrorContainer.AddBinaryError(0, MetadataReaderErrorKind.FileSizeTooSmall); return false; } // Look for DOS Signature "MZ" ushort dosSig = memReader.PeekUInt16(0); if (dosSig != PEFileConstants.DosSignature) { this.ErrorContainer.AddBinaryError(0, MetadataReaderErrorKind.DosHeader); return false; } // Skip the DOS Header int ntHeaderOffset = memReader.PeekInt32(PEFileConstants.PESignatureOffsetLocation); if (!memReader.SeekOffset(ntHeaderOffset)) { this.ErrorContainer.AddBinaryError(memReader.Offset, MetadataReaderErrorKind.FileSizeTooSmall); return false; } // Look for PESignature "PE\0\0" uint NTSignature = memReader.ReadUInt32(); if (NTSignature != PEFileConstants.PESignature) { this.ErrorContainer.AddBinaryError(memReader.Offset - sizeof(uint), MetadataReaderErrorKind.PESignature); return false; } // Read the COFF Header if (!this.ReadCOFFFileHeader(ref memReader)) { return false; } // Read the magic to determine if its PE or PE+ PEMagic magic = (PEMagic)memReader.PeekUInt16(0); switch (magic) { case PEMagic.PEMagic32: if ( !this.ReadOptionalHeaderStandardFields32(ref memReader) || !this.ReadOptionalHeaderNTAdditionalFields32(ref memReader) ) { return false; } break; case PEMagic.PEMagic64: if ( !this.ReadOptionalHeaderStandardFields64(ref memReader) || !this.ReadOptionalHeaderNTAdditionalFields64(ref memReader) ) { return false; } break; default: this.ErrorContainer.AddBinaryError(memReader.Offset, MetadataReaderErrorKind.UnknownPEMagic); return false; } if (!this.ReadOptionalHeaderDirectoryEntries(ref memReader)) { return false; } if (!this.ReadSectionHeaders(ref memReader)) { return false; } this.ReaderState = ReaderState.PEFile; this.Win32ResourceMemoryReader = new MemoryReader(this.DirectoryToMemoryBlock(this.OptionalHeaderDirectoryEntries.ResourceTableDirectory)); return true; }