Пример #1
0
		public override void ProcessCall(RPContext ctx, int instrIndex) {
			Instruction invoke = ctx.Body.Instructions[instrIndex];
			var target = (IMethod)invoke.Operand;

			// Value type proxy is not supported in mild mode.
			if (target.DeclaringType.ResolveTypeDefThrow().IsValueType)
				return;
			// Skipping visibility is not supported in mild mode.
			if (!target.ResolveThrow().IsPublic && !target.ResolveThrow().IsAssembly)
				return;

			Tuple<Code, TypeDef, IMethod> key = Tuple.Create(invoke.OpCode.Code, ctx.Method.DeclaringType, target);
			MethodDef proxy;
			if (!proxies.TryGetValue(key, out proxy)) {
				MethodSig sig = CreateProxySignature(ctx, target, invoke.OpCode.Code == Code.Newobj);

				proxy = new MethodDefUser(ctx.Name.RandomName(), sig);
				proxy.Attributes = MethodAttributes.PrivateScope | MethodAttributes.Static;
				proxy.ImplAttributes = MethodImplAttributes.Managed | MethodImplAttributes.IL;
				ctx.Method.DeclaringType.Methods.Add(proxy);

				// Fix peverify --- Non-virtual call to virtual methods must be done on this pointer
				if (invoke.OpCode.Code == Code.Call && target.ResolveThrow().IsVirtual) {
					proxy.IsStatic = false;
					sig.HasThis = true;
					sig.Params.RemoveAt(0);
				}

				ctx.Marker.Mark(proxy, ctx.Protection);
				ctx.Name.Analyze(proxy);
				ctx.Name.SetCanRename(proxy, false);

				proxy.Body = new CilBody();
				for (int i = 0; i < proxy.Parameters.Count; i++)
					proxy.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, proxy.Parameters[i]));
				proxy.Body.Instructions.Add(Instruction.Create(invoke.OpCode, target));
				proxy.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

				proxies[key] = proxy;
			}

			invoke.OpCode = OpCodes.Call;
			if (ctx.Method.DeclaringType.HasGenericParameters) {
				var genArgs = new GenericVar[ctx.Method.DeclaringType.GenericParameters.Count];
				for (int i = 0; i < genArgs.Length; i++)
					genArgs[i] = new GenericVar(i);

				invoke.Operand = new MemberRefUser(
					ctx.Module,
					proxy.Name,
					proxy.MethodSig,
					new GenericInstSig((ClassOrValueTypeSig)ctx.Method.DeclaringType.ToTypeSig(), genArgs).ToTypeDefOrRef());
			}
			else
				invoke.Operand = proxy;

			var targetDef = target.ResolveMethodDef();
			if (targetDef != null)
				ctx.Context.Annotations.Set(targetDef, ReferenceProxyProtection.Targeted, ReferenceProxyProtection.Targeted);
		}
Пример #2
0
        TypeSig ResolveGenericArgs(TypeSig typeSig)
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            if (ReplaceGenericArg(ref typeSig))
            {
                recursionCounter.Decrement();
                return(typeSig);
            }

            TypeSig result;

            switch (typeSig.ElementType)
            {
            case ElementType.Ptr: result = new PtrSig(ResolveGenericArgs(typeSig.Next)); break;

            case ElementType.ByRef: result = new ByRefSig(ResolveGenericArgs(typeSig.Next)); break;

            case ElementType.Var: result = new GenericVar((typeSig as GenericVar).Number); break;

            case ElementType.ValueArray: result = new ValueArraySig(ResolveGenericArgs(typeSig.Next), (typeSig as ValueArraySig).Size); break;

            case ElementType.SZArray: result = new SZArraySig(ResolveGenericArgs(typeSig.Next)); break;

            case ElementType.MVar: result = new GenericMVar((typeSig as GenericMVar).Number); break;

            case ElementType.CModReqd: result = new CModReqdSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next)); break;

            case ElementType.CModOpt: result = new CModOptSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next)); break;

            case ElementType.Module: result = new ModuleSig((typeSig as ModuleSig).Index, ResolveGenericArgs(typeSig.Next)); break;

            case ElementType.Pinned: result = new PinnedSig(ResolveGenericArgs(typeSig.Next)); break;

            case ElementType.FnPtr: throw new NotSupportedException("FnPtr is not supported.");

            case ElementType.Array:
                ArraySig    arraySig = (ArraySig)typeSig;
                List <uint> sizes    = new List <uint>(arraySig.Sizes);
                List <int>  lbounds  = new List <int>(arraySig.LowerBounds);
                result = new ArraySig(ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds);
                break;

            case ElementType.GenericInst:
                GenericInstSig gis     = (GenericInstSig)typeSig;
                List <TypeSig> genArgs = new List <TypeSig>(gis.GenericArguments.Count);
                foreach (TypeSig ga in gis.GenericArguments)
                {
                    genArgs.Add(ResolveGenericArgs(ga));
                }
                result = new GenericInstSig(ResolveGenericArgs((TypeSig)gis.GenericType) as ClassOrValueTypeSig, genArgs);
                break;

            default:
                result = typeSig;
                break;
            }

            recursionCounter.Decrement();

            return(result);
        }
        private TypeSig ResolveGenericArgs(TypeSig typeSig)
        {
            if (!recursionCounter.Increment())
                return null;

            if (ReplaceGenericArg(ref typeSig)) {
                recursionCounter.Decrement();
                return typeSig;
            }

            TypeSig result;
            switch (typeSig.ElementType) {
                case ElementType.Ptr:
                    result = new PtrSig(ResolveGenericArgs(typeSig.Next));
                    break;
                case ElementType.ByRef:
                    result = new ByRefSig(ResolveGenericArgs(typeSig.Next));
                    break;
                case ElementType.Var:
                    result = new GenericVar((typeSig as GenericVar).Number);
                    break;
                case ElementType.ValueArray:
                    result = new ValueArraySig(ResolveGenericArgs(typeSig.Next), (typeSig as ValueArraySig).Size);
                    break;
                case ElementType.SZArray:
                    result = new SZArraySig(ResolveGenericArgs(typeSig.Next));
                    break;
                case ElementType.MVar:
                    result = new GenericMVar((typeSig as GenericMVar).Number);
                    break;
                case ElementType.CModReqd:
                    result = new CModReqdSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next));
                    break;
                case ElementType.CModOpt:
                    result = new CModOptSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next));
                    break;
                case ElementType.Module:
                    result = new ModuleSig((typeSig as ModuleSig).Index, ResolveGenericArgs(typeSig.Next));
                    break;
                case ElementType.Pinned:
                    result = new PinnedSig(ResolveGenericArgs(typeSig.Next));
                    break;
                case ElementType.FnPtr:
                    throw new NotSupportedException("FnPtr is not supported.");

                case ElementType.Array:
                    var arraySig = (ArraySig)typeSig;
                    var sizes = new List<uint>(arraySig.Sizes);
                    var lbounds = new List<int>(arraySig.LowerBounds);
                    result = new ArraySig(ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds);
                    break;
                case ElementType.GenericInst:
                    var gis = (GenericInstSig)typeSig;
                    var genArgs = new List<TypeSig>(gis.GenericArguments.Count);
                    foreach (TypeSig ga in gis.GenericArguments) {
                        genArgs.Add(ResolveGenericArgs(ga));
                    }
                    result = new GenericInstSig(ResolveGenericArgs(gis.GenericType) as ClassOrValueTypeSig, genArgs);
                    break;

                default:
                    result = typeSig;
                    break;
            }

            recursionCounter.Decrement();

            return result;
        }
Пример #4
0
        /// <summary>
        /// Reads the next type
        /// </summary>
        /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns>
        TypeSig ReadType()
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            uint    num;
            TypeSig nextType, result = null;

            switch ((ElementType)reader.ReadByte())
            {
            case ElementType.Void: result = corLibTypes.Void; break;

            case ElementType.Boolean: result = corLibTypes.Boolean; break;

            case ElementType.Char: result = corLibTypes.Char; break;

            case ElementType.I1: result = corLibTypes.SByte; break;

            case ElementType.U1: result = corLibTypes.Byte; break;

            case ElementType.I2: result = corLibTypes.Int16; break;

            case ElementType.U2: result = corLibTypes.UInt16; break;

            case ElementType.I4: result = corLibTypes.Int32; break;

            case ElementType.U4: result = corLibTypes.UInt32; break;

            case ElementType.I8: result = corLibTypes.Int64; break;

            case ElementType.U8: result = corLibTypes.UInt64; break;

            case ElementType.R4: result = corLibTypes.Single; break;

            case ElementType.R8: result = corLibTypes.Double; break;

            case ElementType.String: result = corLibTypes.String; break;

            case ElementType.TypedByRef: result = corLibTypes.TypedReference; break;

            case ElementType.I: result = corLibTypes.IntPtr; break;

            case ElementType.U: result = corLibTypes.UIntPtr; break;

            case ElementType.Object: result = corLibTypes.Object; break;

            case ElementType.Ptr: result = new PtrSig(ReadType()); break;

            case ElementType.ByRef: result = new ByRefSig(ReadType()); break;

            case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef()); break;

            case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef()); break;

            case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break;

            case ElementType.SZArray: result = new SZArraySig(ReadType()); break;

            case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.Sentinel: result = new SentinelSig(); break;

            case ElementType.Pinned: result = new PinnedSig(ReadType()); break;

            case ElementType.Var:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericVar(num, gpContext.Type);
                break;

            case ElementType.MVar:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericMVar(num, gpContext.Method);
                break;

            case ElementType.ValueArray:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ValueArraySig(nextType, num);
                break;

            case ElementType.Module:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ModuleSig(num, ReadType());
                break;

            case ElementType.GenericInst:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num);
                var args           = genericInstSig.GenericArguments;
                for (uint i = 0; i < num; i++)
                {
                    args.Add(ReadType());
                }
                result = genericInstSig;
                break;

            case ElementType.Array:
                nextType = ReadType();
                uint rank;
                if (!reader.ReadCompressedUInt32(out rank))
                {
                    break;
                }
                if (rank == 0)
                {
                    result = new ArraySig(nextType, rank);
                    break;
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var sizes = new List <uint>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    uint size;
                    if (!reader.ReadCompressedUInt32(out size))
                    {
                        goto exit;
                    }
                    sizes.Add(size);
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var lowerBounds = new List <int>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    int size;
                    if (!reader.ReadCompressedInt32(out size))
                    {
                        goto exit;
                    }
                    lowerBounds.Add(size);
                }
                result = new ArraySig(nextType, rank, sizes, lowerBounds);
                break;

            case ElementType.Internal:
                IntPtr address;
                if (IntPtr.Size == 4)
                {
                    address = new IntPtr(reader.ReadInt32());
                }
                else
                {
                    address = new IntPtr(reader.ReadInt64());
                }
                result = helper.ConvertRTInternalAddress(address);
                break;

            case ElementType.End:
            case ElementType.R:
            default:
                result = null;
                break;
            }
exit:
            recursionCounter.Decrement();
            return(result);
        }
Пример #5
0
        /// <summary>
        /// Imports a <see cref="TypeSig"/>
        /// </summary>
        /// <param name="type">The type</param>
        /// <returns>The imported type or <c>null</c></returns>
        public TypeSig Import(TypeSig type)
        {
            if (type == null)
            {
                return(null);
            }
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            TypeSig result;

            switch (type.ElementType)
            {
            case ElementType.Void:          result = module.CorLibTypes.Void; break;

            case ElementType.Boolean:       result = module.CorLibTypes.Boolean; break;

            case ElementType.Char:          result = module.CorLibTypes.Char; break;

            case ElementType.I1:            result = module.CorLibTypes.SByte; break;

            case ElementType.U1:            result = module.CorLibTypes.Byte; break;

            case ElementType.I2:            result = module.CorLibTypes.Int16; break;

            case ElementType.U2:            result = module.CorLibTypes.UInt16; break;

            case ElementType.I4:            result = module.CorLibTypes.Int32; break;

            case ElementType.U4:            result = module.CorLibTypes.UInt32; break;

            case ElementType.I8:            result = module.CorLibTypes.Int64; break;

            case ElementType.U8:            result = module.CorLibTypes.UInt64; break;

            case ElementType.R4:            result = module.CorLibTypes.Single; break;

            case ElementType.R8:            result = module.CorLibTypes.Double; break;

            case ElementType.String:        result = module.CorLibTypes.String; break;

            case ElementType.TypedByRef: result = module.CorLibTypes.TypedReference; break;

            case ElementType.I:                     result = module.CorLibTypes.IntPtr; break;

            case ElementType.U:                     result = module.CorLibTypes.UIntPtr; break;

            case ElementType.Object:        result = module.CorLibTypes.Object; break;

            case ElementType.Ptr:           result = new PtrSig(Import(type.Next)); break;

            case ElementType.ByRef:         result = new ByRefSig(Import(type.Next)); break;

            case ElementType.ValueType: result = CreateClassOrValueType((type as ClassOrValueTypeSig).TypeDefOrRef, true); break;

            case ElementType.Class:         result = CreateClassOrValueType((type as ClassOrValueTypeSig).TypeDefOrRef, false); break;

            case ElementType.Var:           result = new GenericVar((type as GenericVar).Number); break;

            case ElementType.ValueArray: result = new ValueArraySig(Import(type.Next), (type as ValueArraySig).Size); break;

            case ElementType.FnPtr:         result = new FnPtrSig(Import((type as FnPtrSig).Signature)); break;

            case ElementType.SZArray:       result = new SZArraySig(Import(type.Next)); break;

            case ElementType.MVar:          result = new GenericMVar((type as GenericMVar).Number); break;

            case ElementType.CModReqd:      result = new CModReqdSig(Import((type as ModifierSig).Modifier), Import(type.Next)); break;

            case ElementType.CModOpt:       result = new CModOptSig(Import((type as ModifierSig).Modifier), Import(type.Next)); break;

            case ElementType.Module:        result = new ModuleSig((type as ModuleSig).Index, Import(type.Next)); break;

            case ElementType.Sentinel:      result = new SentinelSig(); break;

            case ElementType.Pinned:        result = new PinnedSig(Import(type.Next)); break;

            case ElementType.Array:
                var arraySig = (ArraySig)type;
                var sizes    = new List <uint>(arraySig.Sizes);
                var lbounds  = new List <int>(arraySig.LowerBounds);
                result = new ArraySig(Import(type.Next), arraySig.Rank, sizes, lbounds);
                break;

            case ElementType.GenericInst:
                var gis     = (GenericInstSig)type;
                var genArgs = new List <TypeSig>(gis.GenericArguments.Count);
                foreach (var ga in gis.GenericArguments)
                {
                    genArgs.Add(Import(ga));
                }
                result = new GenericInstSig(Import(gis.GenericType) as ClassOrValueTypeSig, genArgs);
                break;

            case ElementType.End:
            case ElementType.R:
            case ElementType.Internal:
            default:
                result = null;
                break;
            }

            recursionCounter.Decrement();
            return(result);
        }
Пример #6
0
 void AddGenericVar()
 {
     TypeSig = new GenericVar(genericVariableNumber.Value, options.OwnerType);
 }