Example #1
0
 /// <summary>
 /// Get the instance of <see cref="IILEmitter"/> for the body of the target method.
 /// <see cref="IILEmitter"/> should have all you need to inject code into the target method's body
 /// </summary>
 /// <param name="create">the default is <see langword="true"/>, meaning that new emitter will be created if there's none yet,
 /// set to <see langword="false"/> if you don't want to create new one if none exists, in this case <see langword="null"/> may be returned</param>
 /// <returns>instance of <see cref="IILEmitter"/></returns>
 public IILEmitter GetEmitter(bool create = true)
 {
     if (_emitter == null && create)
     {
         lock (this)
             if (_emitter == null)
             {
                 _emitter = DnextFactory.NewILEmitter(Context.TargetModule, Importer, Fragment);
             }
     }
     return(_emitter);
 }
            public Expr(ICFMangleContext ctx)
                : base(ctx)
            {
                _invCompiled = new CilFragment();
                _stateVar    = new Local(ctx.Method.Module.CorLibTypes.Int32);
                var body = ctx.Method.Body;

                body.Variables.Add(_stateVar);
                body.InitLocals = true;
                var nm    = new IntGenerator(ctx.Mangler.Rng, ctx.Mangler.Options.MaxMangleIterations);
                var codec = nm.Generate();

                codec.ParameterResolver = p => p == nm.Argument ? _stateVar : null;
                _codec = codec;
                var emitter = DnextFactory.NewILEmitter(ctx.Method.Module, ctx.Importer, _invCompiled);

                codec.EmitDemangler(emitter);
            }
        MethodDef CreateFlagCtor(FlagDef flag, Func <MethodSig, bool> validator)
        {
            MethodSig sig;
            var       cats = new List <Tuple <FieldDef, TypeSig> >();
            var       it   = flag.Type;
            var       sm   = it.TypeMapping.Source.Module;

            do
            {
                var qarg = Rng.NextInt32(1, 5);
                cats.Add(Tuple.Create(flag.Field, flag.Field.FieldType));
                var fq = new Queue <FieldDef>(
                    it.TypeMapping.Source.Fields.Where(f => !f.IsStatic & !f.IsLiteral & !f.HasFieldRVA));
                while (cats.Count < qarg)
                {
                    if (fq.Count > 0)
                    {
                        var f = fq.Dequeue();
                        cats.Add(Tuple.Create(f, f.FieldType));
                    }
                    else
                    {
                        cats.Add(Tuple.Create <FieldDef, TypeSig>(null, sm.CorLibTypes.Int32));
                    }
                }

                cats.Shuffle(Rng);
                var args = cats.Select(c => c.Item2).ToArray();
                sig = MethodSig.CreateInstance(sm.CorLibTypes.Void, args);
            } while (!validator(sig));

            var ctor = new MethodDefUser(".ctor", sig, MethodImplAttributes.IL | MethodImplAttributes.Managed,
                                         MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName |
                                         MethodAttributes.Public)
            {
                Body = new CilBody {
                    MaxStack = 8
                }
            };

            var i = 0;

            foreach (var t in cats)
            {
                ctor.ParamDefs.Add(new ParamDefUser("a" + (i++), (ushort)i));
            }
            var     sc = new SigComparer();
            IMethod baseCtor;
            var     bc      = it.Base?.Ctors.RandomElementOrDefault(Rng);
            var     emitter = DnextFactory.NewILEmitter(sm);

            emitter.Emit(OpCodes.Ldarg_0);
            if (bc != null)
            {
                foreach (var pd in bc.Parameters)
                {
                    if (pd.IsNormalMethodParameter)
                    {
                        var f = ctor.Parameters.FirstOrDefault(p =>
                                                               p.IsNormalMethodParameter && sc.Equals(p.Type, pd.Type));
                        if (f != null && Rng.NextBoolean())
                        {
                            emitter.Ldarg(f);
                        }
                        else
                        {
                            Utils.RandomConst(emitter, pd.Type, Rng);
                        }
                    }
                }

                baseCtor = bc;
            }
            else
            {
                baseCtor = new MemberRefUser(sm, ".ctor",
                                             MethodSig.CreateInstance(sm.CorLibTypes.Void),
                                             sm.CorLibTypes.Object.TypeRef);
            }

            emitter.Call(baseCtor);
            Parameter flagpar = null;

            foreach (var p in ctor.Parameters)
            {
                if (p.IsNormalMethodParameter)
                {
                    var t = cats[p.Index - 1];
                    if (t.Item1 != null)
                    {
                        emitter.Emit(OpCodes.Ldarg_0);
                        emitter.Ldarg(p);
                        emitter.Emit(Instruction.Create(OpCodes.Stfld, t.Item1));
                        if (t.Item1 == flag.Field)
                        {
                            flagpar = p;
                        }
                    }
                }
            }

            emitter.Emit(OpCodes.Ret);
            emitter.Replace(ctor.Body);
            flag.SetCtor(ctor, flagpar);
            return(ctor);
        }