internal AssemblyOSTableReader( uint numberOfRows, byte* buffer ) { this.NumberOfRows = numberOfRows; this.OSPlatformIdOffset = 0; this.OSMajorVersionIdOffset = this.OSPlatformIdOffset + sizeof(UInt32); this.OSMinorVersionIdOffset = this.OSMajorVersionIdOffset + sizeof(UInt32); this.RowSize = this.OSMinorVersionIdOffset + sizeof(UInt32); this.AssemblyOSTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
internal FieldSignatureConverter(PEFileToObjectModel peFileToObjectModel, MetadataObject moduleField, MemoryReader signatureMemoryReader) : base(peFileToObjectModel, signatureMemoryReader, moduleField) { //^ base; //^ this.SignatureMemoryReader = signatureMemoryReader; //TODO: Spec# bug. This assignment should not be necessary. this.FirstByte = this.SignatureMemoryReader.ReadByte(); if (!SignatureHeader.IsFieldSignature(this.FirstByte)) { // Error... } bool isPinned; this.customModifiers = this.GetCustomModifiers(out isPinned); this.TypeReference = this.GetTypeReference(); }
bool PopulateCilInstructions() { MethodBodyDocument document = new MethodBodyDocument(this.MethodDefinition); MemoryReader memReader = new MemoryReader(this.MethodIL.EncodedILMemoryBlock); var numInstructions = CountCilInstructions(memReader); if (numInstructions == 0) return true; CilInstruction[] instrList = new CilInstruction[numInstructions]; int instructionNumber = 0; while (memReader.NotEndOfBytes) { object/*?*/ value = null; uint offset = (uint)memReader.Offset; OperationCode cilOpCode = memReader.ReadOpcode(); switch (cilOpCode) { case OperationCode.Nop: case OperationCode.Break: break; case OperationCode.Ldarg_0: case OperationCode.Ldarg_1: case OperationCode.Ldarg_2: case OperationCode.Ldarg_3: value = this.GetParameter((uint)(cilOpCode - OperationCode.Ldarg_0)); break; case OperationCode.Ldloc_0: case OperationCode.Ldloc_1: case OperationCode.Ldloc_2: case OperationCode.Ldloc_3: value = this.GetLocal((uint)(cilOpCode - OperationCode.Ldloc_0)); break; case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: value = this.GetLocal((uint)(cilOpCode - OperationCode.Stloc_0)); break; case OperationCode.Ldarg_S: case OperationCode.Ldarga_S: case OperationCode.Starg_S: value = this.GetParameter(memReader.ReadByte()); break; case OperationCode.Ldloc_S: case OperationCode.Ldloca_S: case OperationCode.Stloc_S: value = this.GetLocal(memReader.ReadByte()); break; case OperationCode.Ldnull: case OperationCode.Ldc_I4_M1: case OperationCode.Ldc_I4_0: case OperationCode.Ldc_I4_1: case OperationCode.Ldc_I4_2: case OperationCode.Ldc_I4_3: case OperationCode.Ldc_I4_4: case OperationCode.Ldc_I4_5: case OperationCode.Ldc_I4_6: case OperationCode.Ldc_I4_7: case OperationCode.Ldc_I4_8: break; case OperationCode.Ldc_I4_S: value = (int)memReader.ReadSByte(); break; case OperationCode.Ldc_I4: value = memReader.ReadInt32(); break; case OperationCode.Ldc_I8: value = memReader.ReadInt64(); break; case OperationCode.Ldc_R4: value = memReader.ReadSingle(); break; case OperationCode.Ldc_R8: value = memReader.ReadDouble(); break; case OperationCode.Dup: case OperationCode.Pop: break; case OperationCode.Jmp: value = this.GetMethod(memReader.ReadUInt32()); break; case OperationCode.Call: { IMethodReference methodReference = this.GetMethod(memReader.ReadUInt32()); IArrayTypeReference/*?*/ arrayType = methodReference.ContainingType as IArrayTypeReference; if (arrayType != null) { // For Get(), Set() and Address() on arrays, the runtime provides method implementations. // Hence, CCI2 replaces these with pseudo instrcutions Array_Set, Array_Get and Array_Addr. // All other methods on arrays will not use pseudo instruction and will have methodReference as their operand. if (methodReference.Name.UniqueKey == this.PEFileToObjectModel.NameTable.Set.UniqueKey) { cilOpCode = OperationCode.Array_Set; value = arrayType; } else if (methodReference.Name.UniqueKey == this.PEFileToObjectModel.NameTable.Get.UniqueKey) { cilOpCode = OperationCode.Array_Get; value = arrayType; } else if (methodReference.Name.UniqueKey == this.PEFileToObjectModel.NameTable.Address.UniqueKey) { cilOpCode = OperationCode.Array_Addr; value = arrayType; } else { value = methodReference; } } else { value = methodReference; } } break; case OperationCode.Calli: value = this.GetFunctionPointerType(memReader.ReadUInt32()); break; case OperationCode.Ret: break; 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: { uint jumpOffset = (uint)(memReader.Offset + 1 + memReader.ReadSByte()); if (jumpOffset >= this.EndOfMethodOffset) { // Error... } value = jumpOffset; } break; 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: { uint jumpOffset = (uint)(memReader.Offset + 4 + memReader.ReadInt32()); if (jumpOffset >= this.EndOfMethodOffset) { // Error... } value = jumpOffset; } break; case OperationCode.Switch: { uint numTargets = memReader.ReadUInt32(); uint[] result = new uint[numTargets]; uint asOffset = memReader.Offset + numTargets * 4; for (int i = 0; i < numTargets; i++) { uint targetAddress = memReader.ReadUInt32() + asOffset; if (targetAddress >= this.EndOfMethodOffset) { // Error... } result[i] = targetAddress; } value = result; } break; case OperationCode.Ldind_I1: case OperationCode.Ldind_U1: case OperationCode.Ldind_I2: case OperationCode.Ldind_U2: case OperationCode.Ldind_I4: case OperationCode.Ldind_U4: case OperationCode.Ldind_I8: case OperationCode.Ldind_I: case OperationCode.Ldind_R4: case OperationCode.Ldind_R8: case OperationCode.Ldind_Ref: case OperationCode.Stind_Ref: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Add: case OperationCode.Sub: case OperationCode.Mul: case OperationCode.Div: case OperationCode.Div_Un: case OperationCode.Rem: case OperationCode.Rem_Un: case OperationCode.And: case OperationCode.Or: case OperationCode.Xor: case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: case OperationCode.Neg: case OperationCode.Not: case OperationCode.Conv_I1: case OperationCode.Conv_I2: case OperationCode.Conv_I4: case OperationCode.Conv_I8: case OperationCode.Conv_R4: case OperationCode.Conv_R8: case OperationCode.Conv_U4: case OperationCode.Conv_U8: break; case OperationCode.Callvirt: { IMethodReference methodReference = this.GetMethod(memReader.ReadUInt32()); IArrayTypeReference/*?*/ arrayType = methodReference.ContainingType as IArrayTypeReference; if (arrayType != null) { // For Get(), Set() and Address() on arrays, the runtime provides method implementations. // Hence, CCI2 replaces these with pseudo instructions Array_Set, Array_Get and Array_Addr. // All other methods on arrays will not use pseudo instruction and will have methodReference as their operand. if (methodReference.Name.UniqueKey == this.PEFileToObjectModel.NameTable.Set.UniqueKey) { cilOpCode = OperationCode.Array_Set; value = arrayType; } else if (methodReference.Name.UniqueKey == this.PEFileToObjectModel.NameTable.Get.UniqueKey) { cilOpCode = OperationCode.Array_Get; value = arrayType; } else if (methodReference.Name.UniqueKey == this.PEFileToObjectModel.NameTable.Address.UniqueKey) { cilOpCode = OperationCode.Array_Addr; value = arrayType; } else { value = methodReference; } } else { value = methodReference; } } break; case OperationCode.Cpobj: case OperationCode.Ldobj: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Ldstr: value = this.GetUserStringForToken(memReader.ReadUInt32()); break; case OperationCode.Newobj: { IMethodReference methodReference = this.GetMethod(memReader.ReadUInt32()); IArrayTypeReference/*?*/ arrayType = methodReference.ContainingType as IArrayTypeReference; if (arrayType != null && !arrayType.IsVector) { uint numParam = IteratorHelper.EnumerableCount(methodReference.Parameters); if (numParam != arrayType.Rank) cilOpCode = OperationCode.Array_Create_WithLowerBound; else cilOpCode = OperationCode.Array_Create; value = arrayType; } else { value = methodReference; } } break; case OperationCode.Castclass: case OperationCode.Isinst: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Conv_R_Un: break; case OperationCode.Unbox: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Throw: break; case OperationCode.Ldfld: case OperationCode.Ldflda: case OperationCode.Stfld: value = this.GetField(memReader.ReadUInt32()); break; case OperationCode.Ldsfld: case OperationCode.Ldsflda: case OperationCode.Stsfld: value = this.GetField(memReader.ReadUInt32()); var fieldRef = value as FieldReference; if (fieldRef != null) fieldRef.isStatic = true; break; case OperationCode.Stobj: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Conv_Ovf_I1_Un: case OperationCode.Conv_Ovf_I2_Un: case OperationCode.Conv_Ovf_I4_Un: case OperationCode.Conv_Ovf_I8_Un: case OperationCode.Conv_Ovf_U1_Un: case OperationCode.Conv_Ovf_U2_Un: case OperationCode.Conv_Ovf_U4_Un: case OperationCode.Conv_Ovf_U8_Un: case OperationCode.Conv_Ovf_I_Un: case OperationCode.Conv_Ovf_U_Un: break; case OperationCode.Box: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Newarr: { var elementType = this.GetType(memReader.ReadUInt32()); if (elementType != null) value = Vector.GetVector(elementType, PEFileToObjectModel.InternFactory); else value = Dummy.ArrayType; } break; case OperationCode.Ldlen: break; case OperationCode.Ldelema: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Ldelem_I1: case OperationCode.Ldelem_U1: case OperationCode.Ldelem_I2: case OperationCode.Ldelem_U2: case OperationCode.Ldelem_I4: case OperationCode.Ldelem_U4: case OperationCode.Ldelem_I8: case OperationCode.Ldelem_I: case OperationCode.Ldelem_R4: case OperationCode.Ldelem_R8: case OperationCode.Ldelem_Ref: case OperationCode.Stelem_I: case OperationCode.Stelem_I1: case OperationCode.Stelem_I2: case OperationCode.Stelem_I4: case OperationCode.Stelem_I8: case OperationCode.Stelem_R4: case OperationCode.Stelem_R8: case OperationCode.Stelem_Ref: break; case OperationCode.Ldelem: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Stelem: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Unbox_Any: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_U8: break; case OperationCode.Refanyval: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Ckfinite: break; case OperationCode.Mkrefany: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Ldtoken: value = this.GetRuntimeHandleFromToken(memReader.ReadUInt32()); break; case OperationCode.Conv_U2: case OperationCode.Conv_U1: case OperationCode.Conv_I: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_U: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: case OperationCode.Endfinally: break; case OperationCode.Leave: { uint leaveOffset = (uint)(memReader.Offset + 4 + memReader.ReadInt32()); if (leaveOffset >= this.EndOfMethodOffset) { // Error... } value = leaveOffset; } break; case OperationCode.Leave_S: { uint leaveOffset = (uint)(memReader.Offset + 1 + memReader.ReadSByte()); if (leaveOffset >= this.EndOfMethodOffset) { // Error... } value = leaveOffset; } break; case OperationCode.Stind_I: case OperationCode.Conv_U: case OperationCode.Arglist: case OperationCode.Ceq: case OperationCode.Cgt: case OperationCode.Cgt_Un: case OperationCode.Clt: case OperationCode.Clt_Un: break; case OperationCode.Ldftn: case OperationCode.Ldvirtftn: value = this.GetMethod(memReader.ReadUInt32()); break; case OperationCode.Ldarg: case OperationCode.Ldarga: case OperationCode.Starg: value = this.GetParameter(memReader.ReadUInt16()); break; case OperationCode.Ldloc: case OperationCode.Ldloca: case OperationCode.Stloc: value = this.GetLocal(memReader.ReadUInt16()); break; case OperationCode.Localloc: value = PointerType.GetPointerType(this.PEFileToObjectModel.PlatformType.SystemVoid, this.PEFileToObjectModel.InternFactory); break; case OperationCode.Endfilter: break; case OperationCode.Unaligned_: value = memReader.ReadByte(); break; case OperationCode.Volatile_: case OperationCode.Tail_: break; case OperationCode.Initobj: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Constrained_: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Cpblk: case OperationCode.Initblk: break; case OperationCode.No_: value = (OperationCheckFlags)memReader.ReadByte(); break; case OperationCode.Rethrow: break; case OperationCode.Sizeof: value = this.GetType(memReader.ReadUInt32()); break; case OperationCode.Refanytype: case OperationCode.Readonly_: break; default: this.PEFileToObjectModel.PEFileReader.ErrorContainer.AddILError(this.MethodDefinition, offset, MetadataReaderErrorKind.UnknownILInstruction); break; } instrList[instructionNumber++] = new CilInstruction(cilOpCode, document, offset, value); } this.MethodBody.SetCilInstructions(instrList); return true; }
bool LoadLocalSignature() { uint locVarRID = this.MethodIL.LocalSignatureToken & TokenTypeIds.RIDMask; if (locVarRID != 0x00000000) { StandAloneSigRow sigRow = this.PEFileToObjectModel.PEFileReader.StandAloneSigTable[locVarRID]; // TODO: error checking offset in range MemoryBlock signatureMemoryBlock = this.PEFileToObjectModel.PEFileReader.BlobStream.GetMemoryBlockAt(sigRow.Signature); // TODO: Error checking enough space in signature memoryBlock. MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock); // TODO: Check if this is really local var signature there. LocalVariableSignatureConverter locVarSigConv = new LocalVariableSignatureConverter(this.PEFileToObjectModel, this.MethodBody, memoryReader); this.MethodBody.SetLocalVariables(locVarSigConv.LocalVariables); } return true; }
internal LocalVariableSignatureConverter( PEFileToObjectModel peFileToObjectModel, MethodBody owningMethodBody, MemoryReader signatureMemoryReader ) : base(peFileToObjectModel, signatureMemoryReader, owningMethodBody.MethodDefinition) { this.OwningMethodBody = owningMethodBody; byte firstByte = this.SignatureMemoryReader.ReadByte(); if (!SignatureHeader.IsLocalVarSignature(firstByte)) { // MDError } int locVarCount = this.SignatureMemoryReader.ReadCompressedUInt32(); LocalVariableDefinition[] locVarArr = new LocalVariableDefinition[locVarCount]; for (int i = 0; i < locVarCount; ++i) { locVarArr[i] = this.GetLocalVariable((uint)i); } this.LocalVariables = locVarArr; }
internal CustomAttributeDecoder(PEFileToObjectModel peFileToObjectModel, MemoryReader signatureMemoryReader, uint customAttributeRowId, IMethodReference attributeConstructor) : base(peFileToObjectModel, signatureMemoryReader) { this.CustomAttribute = Dummy.CustomAttribute; ushort prolog = this.SignatureMemoryReader.ReadUInt16(); if (prolog != SerializationType.CustomAttributeStart) return; int len = attributeConstructor.ParameterCount; IMetadataExpression[]/*?*/ exprList = len == 0 ? null : new IMetadataExpression[len]; int i = 0; foreach (var parameter in attributeConstructor.Parameters) { var parameterType = parameter.Type; if (parameterType is Dummy) { // Error... return; } ExpressionBase/*?*/ argument = this.ReadSerializedValue(parameterType); if (argument == null) { // Error... this.decodeFailed = true; return; } exprList[i++] = argument; } IMetadataNamedArgument[]/*?*/ namedArgumentArray = null; if (2 <= (int)this.SignatureMemoryReader.RemainingBytes) { ushort numOfNamedArgs = this.SignatureMemoryReader.ReadUInt16(); if (numOfNamedArgs > 0) { namedArgumentArray = new IMetadataNamedArgument[numOfNamedArgs]; for (i = 0; i < numOfNamedArgs; ++i) { if (0 >= (int)this.SignatureMemoryReader.RemainingBytes) break; bool isField = this.SignatureMemoryReader.ReadByte() == SerializationType.Field; ITypeReference/*?*/ memberType = this.GetFieldOrPropType(); if (memberType == null) { // Error... return; } string/*?*/ memberStr = this.GetSerializedString(); if (memberStr == null) return; IName memberName = this.PEFileToObjectModel.NameTable.GetNameFor(memberStr); ExpressionBase/*?*/ value = this.ReadSerializedValue(memberType); if (value == null) { // Error... return; } ITypeReference/*?*/ moduleTypeRef = attributeConstructor.ContainingType; if (moduleTypeRef == null) { // Error... return; } FieldOrPropertyNamedArgumentExpression namedArg = new FieldOrPropertyNamedArgumentExpression(memberName, moduleTypeRef, isField, memberType, value); namedArgumentArray[i] = namedArg; } } } this.CustomAttribute = peFileToObjectModel.ModuleReader.metadataReaderHost.Rewrite(peFileToObjectModel.Module, new CustomAttribute(peFileToObjectModel, customAttributeRowId, attributeConstructor, exprList, namedArgumentArray)); }
internal DeclSecurityTableReader( uint numberOfRows, int hasDeclSecurityRefSize, int blobHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsHasDeclSecurityRefSizeSmall = hasDeclSecurityRefSize == 2; this.IsBlobHeapRefSizeSmall = blobHeapRefSize == 2; this.ActionOffset = 0; this.ParentOffset = this.ActionOffset + sizeof(UInt16); this.PermissionSetOffset = this.ParentOffset + hasDeclSecurityRefSize; this.RowSize = this.PermissionSetOffset + blobHeapRefSize; this.DeclSecurityTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
internal CustomAttributeTableReader( uint numberOfRows, int hasCustomAttributeRefSize, int customAttributeTypeRefSize, int blobHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsHasCustomAttributeRefSizeSmall = hasCustomAttributeRefSize == 2; this.IsCustomAttriubuteTypeRefSizeSmall = customAttributeTypeRefSize == 2; this.IsBlobHeapRefSizeSmall = blobHeapRefSize == 2; this.ParentOffset = 0; this.TypeOffset = this.ParentOffset + hasCustomAttributeRefSize; this.ValueOffset = this.TypeOffset + customAttributeTypeRefSize; this.RowSize = this.ValueOffset + blobHeapRefSize; this.CustomAttributeTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
internal static SEHTableEntry[] GetFatSEHEntries( MemoryReader memReader, int numEntries ) { SEHTableEntry[] retSEHEntries = new SEHTableEntry[numEntries]; for (int i = 0; i < numEntries; ++i) { SEHFlags sehFlags = (SEHFlags)memReader.ReadUInt32(); uint tryOffset = memReader.ReadUInt32(); uint tryLength = memReader.ReadUInt32(); uint handlerOffset = memReader.ReadUInt32(); uint handlerLength = memReader.ReadUInt32(); uint classTokenOrFilterOffset = memReader.ReadUInt32(); retSEHEntries[i] = new SEHTableEntry(sehFlags, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFilterOffset); } return retSEHEntries; }
bool ReadMetadataLevelData() //^ requires this.ReaderState >= ReaderState.CORModule; { MemoryReader memReader = new MemoryReader(this.MetadataTableStream); if ( !this.ReadMetadataTableInformation(ref memReader) || !this.ProcessAndCacheMetadataTableBlocks(memReader.RemainingMemoryBlock) ) { return false; } if (this.ModuleTable.NumberOfRows != 1) return false; this.ReaderState = ReaderState.Metadata; return true; }
internal FieldPtrTableReader( uint numberOfRows, int fieldTableRowRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsFieldTableRowRefSizeSmall = fieldTableRowRefSize == 2; this.FieldOffset = 0; this.RowSize = this.FieldOffset + fieldTableRowRefSize; this.FieldPtrTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
bool ReadMetadataTableInformation( ref MemoryReader memReader ) //^ requires this.ReaderState >= ReaderState.CORModule; { if (memReader.RemainingBytes < MetadataStreamConstants.SizeOfMetadataTableHeader) { this.ErrorContainer.AddMetadataStreamError(this.MetadataStreamName, 0, MetadataReaderErrorKind.MetadataTableHeaderTooSmall); return false; } this.MetadataTableHeader.Reserved = memReader.ReadUInt32(); this.MetadataTableHeader.MajorVersion = memReader.ReadByte(); this.MetadataTableHeader.MinorVersion = memReader.ReadByte(); this.MetadataTableHeader.HeapSizeFlags = (HeapSizeFlag)memReader.ReadByte(); this.MetadataTableHeader.RowId = memReader.ReadByte(); this.MetadataTableHeader.ValidTables = (TableMask)memReader.ReadUInt64(); this.MetadataTableHeader.SortedTables = (TableMask)memReader.ReadUInt64(); ulong presentTables = (ulong)this.MetadataTableHeader.ValidTables; ulong validTablesForVersion = 0; int version = this.MetadataTableHeader.MajorVersion << 16 | this.MetadataTableHeader.MinorVersion; switch (version) { case 0x00010000: validTablesForVersion = (ulong)TableMask.V1_0_TablesMask; break; case 0x00010001: validTablesForVersion = (ulong)TableMask.V1_1_TablesMask; break; case 0x00020000: validTablesForVersion = (ulong)TableMask.V2_0_TablesMask; break; default: this.ErrorContainer.AddMetadataStreamError(this.MetadataStreamName, 4, MetadataReaderErrorKind.UnknownVersionOfMetadata); return false; } if ((presentTables & ~validTablesForVersion) != 0) { this.ErrorContainer.AddMetadataStreamError(this.MetadataStreamName, 8, MetadataReaderErrorKind.UnknownTables); return false; } if (this.MetadataStreamKind == MetadataStreamKind.Compressed && (presentTables & (ulong)TableMask.CompressedStreamNotAllowedMask) != 0) { this.ErrorContainer.AddMetadataStreamError(this.MetadataStreamName, 8, MetadataReaderErrorKind.IllegalTablesInCompressedMetadataStream); return false; } ulong requiredSortedTables = presentTables & validTablesForVersion & (ulong)TableMask.SortedTablesMask; if ((requiredSortedTables & (ulong)this.MetadataTableHeader.SortedTables) != requiredSortedTables) { this.ErrorContainer.AddMetadataStreamError(this.MetadataStreamName, 16, MetadataReaderErrorKind.SomeRequiredTablesNotSorted); //Carry on regardless. There are/were compiler out there that sort the required tables, but fail to set the bit in SortedTables. } int numberOfTables = this.MetadataTableHeader.GetNumberOfTablesPresent(); if (memReader.RemainingBytes < numberOfTables * sizeof(Int32)) { this.ErrorContainer.AddMetadataStreamError(this.MetadataStreamName, memReader.Offset, MetadataReaderErrorKind.TableRowCountSpaceTooSmall); return false; } this.MetadataTableRowCount = new uint[numberOfTables]; uint[] metadataTableRowCount = this.MetadataTableRowCount; for (int i = 0; i < numberOfTables; ++i) { metadataTableRowCount[i] = memReader.ReadUInt32(); } return true; }
bool ReadCORModuleLevelData() //^ requires this.ReaderState >= ReaderState.PEFile; { if (!this.ReadCOR20Header()) { return false; } MemoryBlock metadataRoot = this.DirectoryToMemoryBlock(this.COR20Header.MetaDataDirectory); if (metadataRoot.Length < this.COR20Header.MetaDataDirectory.Size) { this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, 0, MetadataReaderErrorKind.NotEnoughSpaceForMetadataDirectory); return false; } MemoryReader memReader = new MemoryReader(metadataRoot); if ( !this.ReadMetadataHeader(ref memReader) || !this.ReadStorageHeader(ref memReader) || !this.ReadStreamHeaders(ref memReader) || !this.ProcessAndCacheStreams(ref metadataRoot) ) { return false; } this.ReaderState = ReaderState.CORModule; this.ResourceMemoryReader = new MemoryReader(this.DirectoryToMemoryBlock(this.COR20Header.ResourcesDirectory)); this.StrongNameSignature = this.DirectoryToMemoryBlock(this.COR20Header.StrongNameSignatureDirectory); return true; }
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; }
bool ReadStorageHeader( ref MemoryReader memReader ) //^ requires this.ReaderState >= ReaderState.PEFile; { if (memReader.RemainingBytes < COR20Constants.SizeofStorageHeader) { this.ErrorContainer.AddDirectoryError(Directories.Cor20HeaderMetaData, memReader.Offset, MetadataReaderErrorKind.StorageHeaderTooSmall); return false; } this.StorageHeader.Flags = memReader.ReadUInt16(); this.StorageHeader.NumberOfStreams = memReader.ReadInt16(); return true; }
internal MemberRefTableReader( uint numberOfRows, int memberRefParentRefSize, int stringHeapRefSize, int blobHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsMemberRefParentRefSizeSmall = memberRefParentRefSize == 2; this.IsStringHeapRefSizeSmall = stringHeapRefSize == 2; this.IsBlobHeapRefSizeSmall = blobHeapRefSize == 2; this.ClassOffset = 0; this.NameOffset = this.ClassOffset + memberRefParentRefSize; this.SignatureOffset = this.NameOffset + stringHeapRefSize; this.RowSize = this.SignatureOffset + blobHeapRefSize; this.MemberRefTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
internal ConstantTableReader( uint numberOfRows, int hasConstantRefSize, int blobHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsHasConstantRefSizeSmall = hasConstantRefSize == 2; this.IsBlobHeapRefSizeSmall = blobHeapRefSize == 2; this.TypeOffset = 0; this.ParentOffset = this.TypeOffset + sizeof(Byte) + 1; // Alignment here (+1)... this.ValueOffset = this.ParentOffset + hasConstantRefSize; this.RowSize = this.ValueOffset + blobHeapRefSize; this.ConstantTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
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 ); }
internal FieldMarshalTableReader( uint numberOfRows, int hasFieldMarshalRefSize, int blobHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsHasFieldMarshalRefSizeSmall = hasFieldMarshalRefSize == 2; this.IsBlobHeapRefSizeSmall = blobHeapRefSize == 2; this.ParentOffset = 0; this.NativeTypeOffset = this.ParentOffset + hasFieldMarshalRefSize; this.RowSize = this.NativeTypeOffset + blobHeapRefSize; this.FieldMarshalTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
internal FieldTableReader( uint numberOfRows, int stringHeapRefSize, int blobHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsStringHeapRefSizeSmall = stringHeapRefSize == 2; this.IsBlobHeapRefSizeSmall = blobHeapRefSize == 2; this.FlagsOffset = 0; this.NameOffset = this.FlagsOffset + sizeof(UInt16); this.SignatureOffset = this.NameOffset + stringHeapRefSize; this.RowSize = this.SignatureOffset + blobHeapRefSize; this.FieldTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
protected AttributeDecoder( PEFileToObjectModel peFileToObjectModel, MemoryReader signatureMemoryReader ) { this.PEFileToObjectModel = peFileToObjectModel; this.SignatureMemoryReader = signatureMemoryReader; this.morePermutationsArePossible = true; }
internal MethodPtrTableReader( uint numberOfRows, int methodTableRowRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsMethodTableRowRefSizeSmall = methodTableRowRefSize == 2; this.MethodOffset = 0; this.RowSize = this.MethodOffset + methodTableRowRefSize; this.MethodPtrTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
internal SecurityAttributeDecoder20(PEFileToObjectModel peFileToObjectModel, MemoryReader signatureMemoryReader, SecurityAttribute securityAttribute) : base(peFileToObjectModel, signatureMemoryReader) { this.SecurityAttributes = Enumerable<ICustomAttribute>.Empty; byte prolog = this.SignatureMemoryReader.ReadByte(); if (prolog != SerializationType.SecurityAttribute20Start) return; int numberOfAttributes = this.SignatureMemoryReader.ReadCompressedUInt32(); var securityCustomAttributes = new ICustomAttribute[numberOfAttributes]; for (int i = 0; i < numberOfAttributes; ++i) { var secAttr = this.ReadSecurityAttribute(securityAttribute); if (secAttr == null) { // MDError... return; } securityCustomAttributes[i] = secAttr; } this.SecurityAttributes = IteratorHelper.GetReadonly(securityCustomAttributes); }
internal MethodTableReader( uint numberOfRows, int paramRefSize, int stringHeapRefSize, int blobHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsParamRefSizeSmall = paramRefSize == 2; this.IsStringHeapRefSizeSmall = stringHeapRefSize == 2; this.IsBlobHeapRefSizeSmall = blobHeapRefSize == 2; this.RVAOffset = 0; this.ImplFlagsOffset = this.RVAOffset + sizeof(UInt32); this.FlagsOffset = this.ImplFlagsOffset + sizeof(UInt16); this.NameOffset = this.FlagsOffset + sizeof(UInt16); this.SignatureOffset = this.NameOffset + stringHeapRefSize; this.ParamListOffset = this.SignatureOffset + blobHeapRefSize; this.RowSize = this.ParamListOffset + paramRefSize; this.MethodTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
internal StandAloneMethodSignatureConverter(PEFileToObjectModel peFileToObjectModel, MethodDefinition moduleMethodDef, MemoryReader signatureMemoryReader) : base(peFileToObjectModel, signatureMemoryReader, moduleMethodDef) { this.RequiredParameters = Enumerable<IParameterTypeInformation>.Empty; this.VarArgParameters = Enumerable<IParameterTypeInformation>.Empty; // TODO: Check minimum required size of the signature... this.FirstByte = this.SignatureMemoryReader.ReadByte(); int paramCount = this.SignatureMemoryReader.ReadCompressedUInt32(); bool dummyPinned; this.ReturnCustomModifiers = this.GetCustomModifiers(out dummyPinned); byte retByte = this.SignatureMemoryReader.PeekByte(0); if (retByte == ElementType.Void) { this.ReturnTypeReference = peFileToObjectModel.PlatformType.SystemVoid; this.SignatureMemoryReader.SkipBytes(1); } else if (retByte == ElementType.TypedReference) { this.ReturnTypeReference = peFileToObjectModel.PlatformType.SystemTypedReference; this.SignatureMemoryReader.SkipBytes(1); } else { if (retByte == ElementType.ByReference) { this.IsReturnByReference = true; this.SignatureMemoryReader.SkipBytes(1); } this.ReturnTypeReference = this.GetTypeReference(); } if (paramCount > 0) { IParameterTypeInformation[] reqModuleParamArr = this.GetModuleParameterTypeInformations(Dummy.Signature, paramCount); if (reqModuleParamArr.Length > 0) this.RequiredParameters = IteratorHelper.GetReadonly(reqModuleParamArr); IParameterTypeInformation[] varArgModuleParamArr = this.GetModuleParameterTypeInformations(Dummy.Signature, paramCount - reqModuleParamArr.Length); if (varArgModuleParamArr.Length > 0) this.VarArgParameters = IteratorHelper.GetReadonly(varArgModuleParamArr); } }
internal ParamPtrTableReader( uint numberOfRows, int paramTableRowRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsParamTableRowRefSizeSmall = paramTableRowRefSize == 2; this.ParamOffset = 0; this.RowSize = this.ParamOffset + paramTableRowRefSize; this.ParamPtrTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
FunctionPointerType/*?*/ GetStandAloneMethodSignature(uint standAloneMethodToken) { StandAloneSigRow sigRow = this.PEFileToObjectModel.PEFileReader.StandAloneSigTable[standAloneMethodToken & TokenTypeIds.RIDMask]; uint signatureBlobOffset = sigRow.Signature; // TODO: error checking offset in range MemoryBlock signatureMemoryBlock = this.PEFileToObjectModel.PEFileReader.BlobStream.GetMemoryBlockAt(signatureBlobOffset); // TODO: Error checking enough space in signature memoryBlock. MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock); // TODO: Check if this is really field signature there. StandAloneMethodSignatureConverter standAloneSigConv = new StandAloneMethodSignatureConverter(this.PEFileToObjectModel, this.MethodDefinition, memoryReader); if (standAloneSigConv.ReturnTypeReference == null) return null; return new FunctionPointerType((CallingConvention)standAloneSigConv.FirstByte, standAloneSigConv.IsReturnByReference, standAloneSigConv.ReturnTypeReference, standAloneSigConv.ReturnCustomModifiers, standAloneSigConv.RequiredParameters, standAloneSigConv.VarArgParameters, this.PEFileToObjectModel.InternFactory); }
internal ParamTableReader( uint numberOfRows, int stringHeapRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsStringHeapRefSizeSmall = stringHeapRefSize == 2; this.FlagsOffset = 0; this.SequenceOffset = this.FlagsOffset + sizeof(UInt16); this.NameOffset = this.SequenceOffset + sizeof(UInt16); this.RowSize = this.NameOffset + stringHeapRefSize; this.ParamTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }
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; }
internal InterfaceImplTableReader( uint numberOfRows, int typeDefTableRowRefSize, int typeDefOrRefRefSize, byte* buffer ) { this.NumberOfRows = numberOfRows; this.IsTypeDefTableRowRefSizeSmall = typeDefTableRowRefSize == 2; this.IsTypeDefOrRefRefSizeSmall = typeDefOrRefRefSize == 2; this.ClassOffset = 0; this.InterfaceOffset = this.ClassOffset + typeDefTableRowRefSize; this.RowSize = this.InterfaceOffset + typeDefOrRefRefSize; this.InterfaceImplTableMemoryReader = new MemoryReader(buffer, (int)(this.RowSize * numberOfRows)); }