private static object ReadRawOperand(IBinaryStreamReader reader, CilOperandType cilOperandType) { switch (cilOperandType) { case CilOperandType.InlineNone: return(null); case CilOperandType.InlineArgument: case CilOperandType.InlineVar: return(reader.ReadUInt16()); case CilOperandType.InlineI: case CilOperandType.InlineBrTarget: return(reader.ReadInt32()); case CilOperandType.ShortInlineArgument: case CilOperandType.ShortInlineVar: return(reader.ReadByte()); case CilOperandType.ShortInlineBrTarget: case CilOperandType.ShortInlineI: return(reader.ReadSByte()); case CilOperandType.ShortInlineR: return(reader.ReadSingle()); case CilOperandType.InlineR: return(reader.ReadDouble()); case CilOperandType.InlineI8: return(reader.ReadInt64()); case CilOperandType.InlineField: case CilOperandType.InlineMethod: case CilOperandType.InlineSig: case CilOperandType.InlineTok: case CilOperandType.InlineType: case CilOperandType.InlineString: return(new MetadataToken(reader.ReadUInt32())); case CilOperandType.InlineSwitch: var offsets = new int[reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; i++) { offsets[i] = reader.ReadInt32(); } return(offsets); } throw new NotSupportedException(); }
private static object ReadRawOperand(IBinaryStreamReader reader, MsilOperandType msilOperandType) { switch (msilOperandType) { case MsilOperandType.InlineNone: return null; case MsilOperandType.InlineArgument: case MsilOperandType.InlineVar: return reader.ReadUInt16(); case MsilOperandType.InlineI: case MsilOperandType.InlineBrTarget: return reader.ReadInt32(); case MsilOperandType.ShortInlineArgument: case MsilOperandType.ShortInlineVar: return reader.ReadByte(); case MsilOperandType.ShortInlineBrTarget: case MsilOperandType.ShortInlineI: return reader.ReadSByte(); case MsilOperandType.ShortInlineR: return reader.ReadSingle(); case MsilOperandType.InlineR: return reader.ReadDouble(); case MsilOperandType.InlineI8: return reader.ReadInt64(); case MsilOperandType.InlineField : case MsilOperandType.InlineMethod : case MsilOperandType.InlineSig: case MsilOperandType.InlineTok: case MsilOperandType.InlineType: case MsilOperandType.InlineString: return new MetadataToken(reader.ReadUInt32()); case MsilOperandType.InlineSwitch: var offsets = new int[reader.ReadUInt32()]; for (int i = 0; i < offsets.Length; i++) offsets[i] = reader.ReadInt32(); return offsets; } throw new NotSupportedException(); }
private static object ReadElement(IBinaryStreamReader reader, ElementType elementType) { switch (elementType) { case ElementType.I1: return(reader.ReadSByte()); case ElementType.I2: return(reader.ReadInt16()); case ElementType.I4: return(reader.ReadInt32()); case ElementType.I8: return(reader.ReadInt64()); case ElementType.U1: return(reader.ReadByte()); case ElementType.U2: return(reader.ReadUInt16()); case ElementType.U4: return(reader.ReadUInt32()); case ElementType.U8: return(reader.ReadUInt64()); case ElementType.R4: return(reader.ReadSingle()); case ElementType.R8: return(reader.ReadDouble()); } ThrowUnsupportedElementType(elementType); return(null); }
/// <summary> /// Reads a type signature from a blob reader. /// </summary> /// <param name="module">The module containing the blob signature.</param> /// <param name="reader">The blob signature reader.</param> /// <param name="protection">The object responsible for detecting infinite recursion.</param> /// <returns>The type signature.</returns> /// <exception cref="ArgumentOutOfRangeException">Occurs when the blob reader points to an element type that is /// invalid or unsupported.</exception> public static TypeSignature FromReader(ModuleDefinition module, IBinaryStreamReader reader, RecursionProtection protection) { var elementType = (ElementType)reader.ReadByte(); switch (elementType) { case ElementType.Void: case ElementType.Boolean: case ElementType.Char: case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.String: case ElementType.I: case ElementType.U: case ElementType.TypedByRef: case ElementType.Object: return(module.CorLibTypeFactory.FromElementType(elementType)); case ElementType.ValueType: return(new TypeDefOrRefSignature(ReadTypeDefOrRef(module, reader, protection, false), true)); case ElementType.Class: return(new TypeDefOrRefSignature(ReadTypeDefOrRef(module, reader, protection, false), false)); case ElementType.Ptr: return(new PointerTypeSignature(FromReader(module, reader, protection))); case ElementType.ByRef: return(new ByReferenceTypeSignature(FromReader(module, reader, protection))); case ElementType.Var: return(new GenericParameterSignature(module, GenericParameterType.Type, (int)reader.ReadCompressedUInt32())); case ElementType.MVar: return(new GenericParameterSignature(module, GenericParameterType.Method, (int)reader.ReadCompressedUInt32())); case ElementType.Array: return(ArrayTypeSignature.FromReader(module, reader, protection)); case ElementType.GenericInst: return(GenericInstanceTypeSignature.FromReader(module, reader, protection)); case ElementType.FnPtr: throw new NotImplementedException(); case ElementType.SzArray: return(new SzArrayTypeSignature(FromReader(module, reader, protection))); case ElementType.CModReqD: return(new CustomModifierTypeSignature( ReadTypeDefOrRef(module, reader, protection, true), true, FromReader(module, reader, protection))); case ElementType.CModOpt: return(new CustomModifierTypeSignature( ReadTypeDefOrRef(module, reader, protection, true), false, FromReader(module, reader, protection))); case ElementType.Sentinel: return(new SentinelTypeSignature()); case ElementType.Pinned: return(new PinnedTypeSignature(FromReader(module, reader, protection))); case ElementType.Boxed: return(new BoxedTypeSignature(FromReader(module, reader, protection))); case ElementType.Internal: IntPtr address = IntPtr.Size switch { 4 => new IntPtr(reader.ReadInt32()), _ => new IntPtr(reader.ReadInt64()) }; //Get Internal Method Through Reflection var GetTypeFromHandleUnsafeReflection = typeof(Type) .GetMethod("GetTypeFromHandleUnsafe", ((BindingFlags)(-1)), null, new[] { typeof(IntPtr) }, null); //Invoke It To Get The Value var Type = (Type)GetTypeFromHandleUnsafeReflection?.Invoke(null, new object[] { address }); //Import it return(new TypeDefOrRefSignature(new ReferenceImporter(module).ImportType((Type)))); default: throw new ArgumentOutOfRangeException($"Invalid or unsupported element type {elementType}."); } }
private static object ReadValue(MetadataHeader header, TypeSignature typeSignature, IBinaryStreamReader reader) { switch (typeSignature.ElementType) { case ElementType.Boolean: return(reader.ReadByte() == 1); case ElementType.Char: return((char)reader.ReadUInt16()); case ElementType.R4: return(reader.ReadSingle()); case ElementType.R8: return(reader.ReadDouble()); case ElementType.I1: return(reader.ReadSByte()); case ElementType.I2: return(reader.ReadInt16()); case ElementType.I4: return(reader.ReadInt32()); case ElementType.I8: return(reader.ReadInt64()); case ElementType.U1: return(reader.ReadByte()); case ElementType.U2: return(reader.ReadUInt16()); case ElementType.U4: return(reader.ReadUInt32()); case ElementType.U8: return(reader.ReadUInt64()); case ElementType.String: return(reader.ReadSerString()); case ElementType.Object: case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = header.MetadataResolver.ResolveType(typeSignature); if (enumTypeDef == null) { throw new MemberResolutionException(typeSignature); } if (enumTypeDef.IsEnum) { return(ReadValue(header, enumTypeDef.GetEnumUnderlyingType(), reader)); } break; } if (typeSignature.IsTypeOf("System", "Type")) { return(reader.ReadSerString()); } throw new NotSupportedException("Unsupported element type " + typeSignature.ElementType); }
private static object ReadValue(ModuleDefinition parentModule, TypeSignature valueType, IBinaryStreamReader reader) { switch (valueType.ElementType) { case ElementType.Boolean: return(reader.ReadByte() == 1); case ElementType.Char: return((char)reader.ReadUInt16()); case ElementType.R4: return(reader.ReadSingle()); case ElementType.R8: return(reader.ReadDouble()); case ElementType.I1: return(reader.ReadSByte()); case ElementType.I2: return(reader.ReadInt16()); case ElementType.I4: return(reader.ReadInt32()); case ElementType.I8: return(reader.ReadInt64()); case ElementType.U1: return(reader.ReadByte()); case ElementType.U2: return(reader.ReadUInt16()); case ElementType.U4: return(reader.ReadUInt32()); case ElementType.U8: return(reader.ReadUInt64()); case ElementType.String: return(reader.ReadSerString()); case ElementType.Object: return(ReadValue(parentModule, TypeSignature.ReadFieldOrPropType(parentModule, reader), reader)); case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = parentModule.MetadataResolver.ResolveType(valueType); if (enumTypeDef != null && enumTypeDef.IsEnum) { return(ReadValue(parentModule, enumTypeDef.GetEnumUnderlyingType(), reader)); } break; } if (valueType.IsTypeOf("System", "Type")) { return(TypeNameParser.Parse(parentModule, reader.ReadSerString())); } throw new NotSupportedException($"Unsupported element type {valueType.ElementType}."); }
private static object ReadValue(MetadataHeader header, TypeSignature typeSignature, IBinaryStreamReader reader) { switch (typeSignature.ElementType) { case ElementType.Boolean: return reader.ReadByte() == 1; case ElementType.Char: return (char)reader.ReadUInt16(); case ElementType.R4: return reader.ReadSingle(); case ElementType.R8: return reader.ReadDouble(); case ElementType.I1: return reader.ReadSByte(); case ElementType.I2: return reader.ReadInt16(); case ElementType.I4: return reader.ReadInt32(); case ElementType.I8: return reader.ReadInt64(); case ElementType.U1: return reader.ReadByte(); case ElementType.U2: return reader.ReadUInt16(); case ElementType.U4: return reader.ReadUInt32(); case ElementType.U8: return reader.ReadUInt64(); case ElementType.String: return reader.ReadSerString(); case ElementType.Object: return ReadValue(header, TypeSignature.ReadFieldOrPropType(header, reader), reader); case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: var enumTypeDef = header.MetadataResolver.ResolveType(typeSignature); if (enumTypeDef == null) throw new MemberResolutionException(typeSignature); if (enumTypeDef.IsEnum) return ReadValue(header, enumTypeDef.GetEnumUnderlyingType(), reader); break; } if (typeSignature.IsTypeOf("System", "Type")) return TypeSignature.FromAssemblyQualifiedName(header, reader.ReadSerString()); throw new NotSupportedException("Unsupported element type " + typeSignature.ElementType); }
private object ReadOperand(CilOperandType operandType) { switch (operandType) { case CilOperandType.InlineNone: return(null); case CilOperandType.ShortInlineI: return(_reader.ReadSByte()); case CilOperandType.ShortInlineBrTarget: return(new CilOffsetLabel(_reader.ReadSByte() + (int)(_reader.Offset - _reader.StartOffset))); case CilOperandType.ShortInlineVar: byte shortLocalIndex = _reader.ReadByte(); return(_operandResolver?.ResolveLocalVariable(shortLocalIndex) ?? shortLocalIndex); case CilOperandType.ShortInlineArgument: byte shortArgIndex = _reader.ReadByte(); return(_operandResolver?.ResolveParameter(shortArgIndex) ?? shortArgIndex); case CilOperandType.InlineVar: ushort longLocalIndex = _reader.ReadUInt16(); return(_operandResolver?.ResolveLocalVariable(longLocalIndex) ?? longLocalIndex); case CilOperandType.InlineArgument: ushort longArgIndex = _reader.ReadUInt16(); return(_operandResolver?.ResolveParameter(longArgIndex) ?? longArgIndex); case CilOperandType.InlineI: return(_reader.ReadInt32()); case CilOperandType.InlineBrTarget: return(new CilOffsetLabel(_reader.ReadInt32() + (int)(_reader.Offset - _reader.StartOffset))); case CilOperandType.ShortInlineR: return(_reader.ReadSingle()); case CilOperandType.InlineI8: return(_reader.ReadInt64()); case CilOperandType.InlineR: return(_reader.ReadDouble()); case CilOperandType.InlineString: var stringToken = new MetadataToken(_reader.ReadUInt32()); return(_operandResolver?.ResolveString(stringToken) ?? stringToken); case CilOperandType.InlineField: case CilOperandType.InlineMethod: case CilOperandType.InlineSig: case CilOperandType.InlineTok: case CilOperandType.InlineType: var memberToken = new MetadataToken(_reader.ReadUInt32()); return(_operandResolver?.ResolveMember(memberToken) ?? memberToken); case CilOperandType.InlinePhi: throw new NotSupportedException(); case CilOperandType.InlineSwitch: return(ReadSwitchTable()); default: throw new ArgumentOutOfRangeException(nameof(operandType), operandType, null); } }
public void ReadValue(TypeSignature valueType) { if (valueType.IsTypeOf("System", "Type")) { Elements.Add(TypeNameParser.Parse(_parentModule, _reader.ReadSerString())); return; } switch (valueType.ElementType) { case ElementType.Boolean: Elements.Add(_reader.ReadByte() == 1); break; case ElementType.Char: Elements.Add((char)_reader.ReadUInt16()); break; case ElementType.R4: Elements.Add(_reader.ReadSingle()); break; case ElementType.R8: Elements.Add(_reader.ReadDouble()); break; case ElementType.I1: Elements.Add(_reader.ReadSByte()); break; case ElementType.I2: Elements.Add(_reader.ReadInt16()); break; case ElementType.I4: Elements.Add(_reader.ReadInt32()); break; case ElementType.I8: Elements.Add(_reader.ReadInt64()); break; case ElementType.U1: Elements.Add(_reader.ReadByte()); break; case ElementType.U2: Elements.Add(_reader.ReadUInt16()); break; case ElementType.U4: Elements.Add(_reader.ReadUInt32()); break; case ElementType.U8: Elements.Add(_reader.ReadUInt64()); break; case ElementType.String: Elements.Add(_reader.ReadSerString()); break; case ElementType.Object: var reader = new CustomAttributeArgumentReader(_parentModule, _reader); var type = TypeSignature.ReadFieldOrPropType(_parentModule, _reader); reader.ReadValue(type); Elements.Add(new BoxedArgument(type, type.ElementType == ElementType.SzArray ? reader.Elements.ToArray() : reader.Elements[0])); break; case ElementType.SzArray: var arrayElementType = ((SzArrayTypeSignature)valueType).BaseType; uint elementCount = _reader.CanRead(sizeof(uint)) ? _reader.ReadUInt32() : uint.MaxValue; IsNullArray = elementCount == uint.MaxValue; if (!IsNullArray) { for (uint i = 0; i < elementCount; i++) { ReadValue(arrayElementType); } } break; case ElementType.Class: case ElementType.Enum: case ElementType.ValueType: // Value is an enum, resolve it and get underlying type. // If that fails, most enums are int32s, assume that is the case in an attempt to recover. var enumTypeDef = _parentModule.MetadataResolver.ResolveType(valueType); TypeSignature underlyingType; if (enumTypeDef is null) { underlyingType = _parentModule.CorLibTypeFactory.Int32; } else if (enumTypeDef.IsEnum) { underlyingType = enumTypeDef.GetEnumUnderlyingType() ?? _parentModule.CorLibTypeFactory.Int32; } else { throw new NotSupportedException($"Type {valueType} is not an enum."); } ReadValue(underlyingType); break; default: throw new NotSupportedException($"Unsupported element type {valueType.ElementType}."); } }