示例#1
0
        protected override void Handle(NetfuserEvent ev)
        {
            switch (ev)
            {
            case NetfuserEvent.InjectResources injr:
                Parallel.ForEach(_entries, e => e.Initialize());
                injr.Add(_index);
                foreach (var embedding in _entries)
                {
                    injr.Add(embedding.Resource);
                }
                break;

            case NetfuserEvent.InjectTypes inj:
                if (Name != NetfuserFactory.EmbedderIndexName)
                {
                    break;
                }
                var ep = Context.MainSourceModule.EntryPoint;
                if (ep == null)
                {
                    throw Context.Error("assemblies can be embedded only in executable target");
                }
                inj.Add(RuntimeUtils.TypesToInject);
                var decompTypes = _entries.Select(e => e.Compression?.RuntimeDecompressorType)
                                  .Where(t => t != null).ToList();
                if (decompTypes.Count > 0)
                {
                    inj.Add(decompTypes);
                }
                var decryptTypes = _entries.Select(e => e.Encryption?.RuntimeDecryptorType)
                                   .Where(t => t != null).ToList();
                if (decryptTypes.Count > 0)
                {
                    inj.Add(decryptTypes);
                }

                Context.OfType <NetfuserEvent.CilBodyBuilding>().Where(me => me.Source == ep).Take(1).Subscribe(me =>
                {
                    if (!Context.MappedTypes.TryGetValue(typeof(EmbeddedAssemblyResolver).CreateKey(),
                                                         out var mapping))
                    {
                        return;
                    }
                    var bootstrap = mapping.Target.Methods.FirstOrDefault(m =>
                                                                          m.IsStatic && !m.IsConstructor && !m.IsRuntimeSpecialName);
                    var il = me.GetEmitter();
                    il.MainFragment.Instructions.Insert(0, Instruction.Create(OpCodes.Call, bootstrap));
                    var name = Context.MappedResources[DnextFactory.NewTypeKey(null, _index)].Target.Name;
                    il.MainFragment.Instructions.Insert(0, Instruction.Create(OpCodes.Ldstr, name));
                });
                break;
            }
        }
示例#2
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);
 }
示例#3
0
 void MapForwardedTypes(IEnumerable <ModuleDef> modules)
 {
     foreach (var mod in modules)
     {
         foreach (var exp in mod.ExportedTypes)
         {
             if (exp.IsForwarder)
             {
                 _forwardedTypes.Add(DnextFactory.NewTypeKey(mod, exp.FullName), exp.ToTypeRef());
             }
         }
     }
 }
示例#4
0
        public Stream OpenReader()
        {
            var root = new XElement("index");
            var doc  = new XDocument(root);

            foreach (var embedding in _entries)
            {
                var res   = embedding.Resource;
                var name  = Context.MappedResources[DnextFactory.NewTypeKey(null, res)].Target.Name;
                var entry = new XElement("entry");
                if (embedding.Properties != null)
                {
                    foreach (var kv in embedding.Properties)
                    {
                        entry.SetAttributeValue(kv.Key, kv.Value);
                    }
                }
                entry.SetAttributeValue(ResourceEntry.KeyName, embedding.Name);
                entry.SetAttributeValue(ResourceEntry.KeyResourceName, name);
                if (embedding.Compression != null)
                {
                    if (!Context.MappedTypes.TryGetValue(embedding.Compression.RuntimeDecompressorType.CreateKey(),
                                                         out var mapping))
                    {
                        throw Context.Error("could not find decompressor type in target assembly");
                    }
                    entry.SetAttributeValue(ResourceEntry.KeyCompression, mapping.Target.MDToken.Raw);
                }
                if (embedding.Encryption != null)
                {
                    if (!Context.MappedTypes.TryGetValue(embedding.Encryption.RuntimeDecryptorType.CreateKey(),
                                                         out var mapping))
                    {
                        throw Context.Error("could not find decryptor type in target assembly");
                    }
                    entry.SetAttributeValue(ResourceEntry.KeyEncryption, mapping.Target.MDToken.Raw);
                }
                root.Add(entry);
            }

            var ms = new MemoryStream();

            using (var writer = new XmlTextWriter(new StreamWriter(ms, Encoding.UTF8, 16384, true)))
                doc.WriteTo(writer);
            ms.Position = 0;
            return(ms);
        }
            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);
            }
示例#6
0
        bool Emit(IILEmitter emitter, ref Local local, bool upper, bool invert, Instruction falseTarget)
        {
            var ic = upper ? _upper : _lower;

            if (!ic.HasValue)
            {
                return(false);
            }
            var c        = Base.Lang.Ints.Const(ic.Value.Value, Bytes, Signed);
            var compiler = new ExprCompiler(emitter);

            if (invert)
            {
                if (local == null)
                {
                    local = emitter.RequestTempLocal(c.Type);
                    emitter.Stloc(local);
                }

                compiler.Compile(c);
                emitter.Ldloc(local);
                var op = DnextFactory.CondBranch(upper, !ic.Value.Inclusive, Signed);
                emitter.Emit(op, falseTarget);
            }
            else
            {
                if (local != null)
                {
                    emitter.Ldloc(local);
                }
                compiler.Compile(c);
                var op = DnextFactory.CondBranch(!upper, !ic.Value.Inclusive, Signed);
                emitter.Emit(op, falseTarget);
            }

            return(true);
        }
示例#7
0
        internal void Run()
        {
            var target = Context.TargetModule;

            if (_source.HasResources)
            {
                foreach (var r in _source.Resources)
                {
                    if (r is LinkedResource lr &&
                        Context.MappedResources.TryGetValue(DnextFactory.NewTypeKey(_source, r), out var mapping) &&
                        mapping.Target is LinkedResource tlr && tlr.File == lr.File)
                    {
                        tlr.File = Clone(lr.File);
                    }
                }
            }


            if (_source == Context.MainSourceModule)
            {
                if (_source.Win32Resources != null)
                {
                    target.Win32Resources = _source.Win32Resources;
                }
                var sourceAssembly = _source.Assembly;
                var targetAssembly = target.Assembly;
                CopyCustomAttributes(_source, target);
                CopyCustomAttributes(sourceAssembly, targetAssembly);
                CopyCustomDebugInfo(_source, target);
                CopyCustomDebugInfo(sourceAssembly, targetAssembly);
                CopyDeclSecurities(sourceAssembly, targetAssembly);
                if (_source.IsEntryPointValid)
                {
                    target.EntryPoint = Importer.Import(_source.EntryPoint).ResolveMethodDef();
                }
            }
        }
示例#8
0
        protected override void Handle(NetfuserEvent ev)
        {
            switch (ev)
            {
            case NetfuserEvent.Initialize _:
                if (Options.Generator == null)
                {
                    Options.Generator = Context.DebugMode ? (NameGenerator) new NameGenerator.Debug() : new NameGenerator.Hash();
                }
                break;

            case NetfuserEvent.TypeSkeletonsImported e:
                if ((_options.Type & MetaType.Method) != 0)
                {
                    _nameChains = DnextFactory.BuildVNameChains(Context.Plugin <IVTablePlugin>().VTables,
                                                                Context.MappedTypes.Values.Select(m => m.Source), m =>
                                                                !Context.MappedTypes.TryGetValue(m.DeclaringType.CreateKey(), out var tm) ||
                                                                DontRename(tm, m));
                }

                // build scopes for types with preserved names first
                foreach (var tm in Context.MappedTypes.Values.Where(m =>
                                                                    _ns.IsPreserved(m, MetaType.NamespaceAndType)))
                {
                    Prepopulate(tm);
                }
                if (_options.NamespaceMangling == NamespaceMangling.Distribute)
                {
                    var count = (int)Math.Sqrt(Context.MappedTypes.Count);
                    for (var i = 0; i < count; i++)
                    {
                        GetNode(_root, null, i.ToString());
                    }
                }

                // build scopes for the remaining types and their preserved member names
                foreach (var tm in Context.MappedTypes.Values.Where(m =>
                                                                    !_ns.IsPreserved(m, MetaType.NamespaceAndType)))
                {
                    Prepopulate(tm);
                }

                if ((_options.Type & MetaType.Method) != 0)
                {
                    // add virtual renamable methods before regular methods
                    // we use fake scope here
                    var scope = new MetadataElement(null, string.Empty);

                    foreach (var c in _nameChains.All())
                    {
                        if (!c.DontRename)
                        {
                            c.NewName = NameGenerator(scope, null, c.Name,
                                                      n => MatchesTypeOrMemberName(c.Types, n));
                        }
                    }
                }

                break;

            case NetfuserEvent.CreateMethod cm when(_options.Type& MetaType.Method) != 0:
                cm.Target.Name = GetMangledName(cm.TypeMapping, cm.Source);

                break;

            case NetfuserEvent.CreateField cm when(_options.Type& MetaType.Field) != 0:
                cm.Target.Name = GetMangledName(cm.TypeMapping, cm.Source);

                break;

            case NetfuserEvent.CreateProperty cm when(_options.Type& MetaType.Property) != 0:
                cm.Target.Name = GetMangledName(cm.TypeMapping, cm.Source);

                break;

            case NetfuserEvent.CreateEvent cm when(_options.Type& MetaType.Event) != 0:
                cm.Target.Name = GetMangledName(cm.TypeMapping, cm.Source);

                break;

            case NetfuserEvent.CreateMethodParameter cm when(_options.Type& MetaType.Method) != 0:
                // fast and easy way to check if we should rename parameter names:
                // if renaming didn't happen for this method, there's little sense to rename its parameters.
                // someone may even rely on parameter names [theoretically], as they are available via reflection
                // However, we allow one exception - RTSpecialNames (.ctors), as they are never renamed
                var method = cm.Source.DeclaringMethod;

                if (!method.IsRuntimeSpecialName && GetMangledName(cm.TypeMapping, method) == method.Name)
                {
                    break;
                }

                cm.Target.Name = _options.Generator.Generate(this, cm.Source);
                break;

            case NetfuserEvent.CreateGenericParameter cm:
                method = cm.Source.DeclaringMethod;
                if (method != null)
                {
                    if (!method.IsRuntimeSpecialName && GetMangledName(cm.TypeMapping, method) == method.Name)
                    {
                        break;
                    }
                }
                else if (cm.Source.DeclaringType != null)
                {
                    if (GetNode(cm.TypeMapping).NewName == cm.Source.DeclaringType.Name)
                    {
                        break;
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }

                cm.Target.Name = _options.Generator.Generate(this, cm.Source);
                break;

            case NetfuserEvent.ResourcesDeclared rde:
                var rs       = new MetadataElement(null, string.Empty);
                var newNames = new HashSet <string>(Context.MappedResources.Values.Select(m => (string)m.Target.Name));
                foreach (var rm in Context.MappedResources.Values.Where(m => !_ns.IsPreserved(m)))
                {
                    var oldName = rm.Target.Name;
                    var newName = NameGenerator(rs, null, rm.Source.Name, n => newNames.Contains(n));
                    if (newName != oldName)
                    {
                        newNames.Remove(oldName);
                        newNames.Add(newName);
                        rm.Target.Name = newName;
                    }
                }
                break;
            }
        }
示例#9
0
        void MapResources(IEnumerable <ModuleDef> modules)
        {
            var resourcesByName = new Dictionary <string, Resource>();

            foreach (var module in modules)
            {
                if (module.HasResources)
                {
                    foreach (var source in module.Resources)
                    {
                        Import(module, source);
                    }
                }
            }

            var inject = Fire(new NetfuserEvent.InjectResources(this)).Resources;

            foreach (var resource in inject)
            {
                Import(null, resource);
            }

            Fire(new NetfuserEvent.ResourcesDeclared(this));

            void Import(ModuleDef module, Resource source)
            {
                string name;

                if (resourcesByName.TryGetValue(source.Name, out var target))
                {
                    name = Duplicate(module, source, target);
                }
                else
                {
                    name = source.Name;
                }

                target = Fire(new NetfuserEvent.CreateResource(this, module, source)
                {
                    Target = Clone(source)
                }).Target;
                _targetModule.Resources.Add(target);
                resourcesByName.Add(name, target);

                var key = DnextFactory.NewTypeKey(module, source);
                var tm  = new ResourceMapping(module, source, target);

                _resourceMappings.Add(key, tm);
                Fire(new NetfuserEvent.ResourceMapped(this, tm));
            }

            string Duplicate(ModuleDef sourceModule, Resource source, Resource target)
            {
                var ev = new NetfuserEvent.DuplicateResource(this, sourceModule, source, target);
                var c  = 0;

                do
                {
                    ev.RenameInto = source.Name + "_" + ++c;
                } while (resourcesByName.ContainsKey(ev.RenameInto));

                Fire(ev);
                var result = ev.RenameInto;

                if (string.IsNullOrEmpty(result) || resourcesByName.ContainsKey(result))
                {
                    throw Error("resource name must be unique, non-null and non-empty");
                }
                return(result);
            }

            Resource Clone(Resource source)
            {
                switch (source)
                {
                case EmbeddedResource er:
                    return(er.SharedClone());

                case AssemblyLinkedResource alr:
                    return(new AssemblyLinkedResource(alr.Name, alr.Assembly, alr.Attributes));

                case LinkedResource lr:
                    // we will later replace the File property with the clone FileDef, unless someone else changes it
                    return(new LinkedResource(lr.Name, lr.File, lr.Attributes));
                }

                throw new NotSupportedException();
            }
        }
示例#10
0
            public void Mangle(Block.Regular block)
            {
                var rng       = _switch.Mangler.Rng;
                var fi        = _context.RootBlock.FlowInfo.Info;
                var fragments = _context.SplitFragments(block);

                if (fragments.Count < 3)
                {
                    return;
                }

                int i;
                var keyId = Enumerable.Range(0, fragments.Count).ToArray();

                keyId.Shuffle(rng);
                var key = new int[keyId.Length];

                for (i = 0; i < key.Length; i++)
                {
                    var q = rng.NextInt32() & 0x7fffffff;
                    key[i] = q - q % fragments.Count + keyId[i];
                }

                var statementKeys = new Dictionary <Instruction, int>();
                var current       = fragments.First;

                i = 0;
                while (current != null)
                {
                    if (i != 0)
                    {
                        statementKeys[current.Value.First] = key[i];
                    }
                    i++;
                    current = current.Next;
                }

                var lastInstructions          = new HashSet <Instruction>(fragments.Select(f => f.Last()));
                var blockInstructions         = new HashSet <Instruction>(block.Fragment);
                var firstFragmentInstructions = new HashSet <Instruction>(fragments.First());

                bool HasUnknownSource(IEnumerable <Instruction> instrs) =>
                instrs.Any(instr =>
                {
                    //return true;
                    fi.TryGetValue(instr, out var info);
                    if (info.RefCount > 1)
                    {
                        return(true);
                    }
                    Debug.Assert(info.RefCount == 1);
                    var srcs = info.ReferencedBy;
                    if (srcs.Count == 0)
                    {
                        return(false);
                    }
                    Debug.Assert(srcs.Count == 1);
                    var src = srcs[0];
                    return
                    // Target of switch => assume unknown
                    (src.OpCode.Code == Code.Switch        // Operand is Instruction[]
                                                           // Not targeted by the last of statements
                     || lastInstructions.Contains(src)
                     // Not within current instruction block / targeted in first statement
                     // || src.Offset <= fragments.First.Value.Last().Offset || src.Offset >= block.Fragment.Last().Offset
                     || !blockInstructions.Contains(src) ||
                     firstFragmentInstructions.Contains(src));
                });

                var switchInstr = new Instruction(OpCodes.Switch);
                var switchHdr   = new CilFragment();

                if (_predicate != null)
                {
                    switchHdr.Add(Instruction.CreateLdcI4(_predicate.GetSwitchKey(key[1])));
                    _predicate.EmitSwitchLoad(switchHdr);
                }
                else
                {
                    switchHdr.Add(Instruction.CreateLdcI4(key[1]));
                }

                switchHdr.Add(Instruction.Create(OpCodes.Dup));
                switchHdr.Add(Instruction.Create(OpCodes.Stloc, _local));
                switchHdr.Add(Instruction.Create(OpCodes.Ldc_I4, fragments.Count));
                switchHdr.Add(Instruction.Create(OpCodes.Rem_Un));
                switchHdr.Add(switchInstr);

                _context.AddJump(switchHdr, fragments.Last.Value.First, true);
                var switchHdrSecond = switchHdr.Instructions[1];

                var operands = new Instruction[fragments.Count];

                current = fragments.First;
                i       = 0;
                while (current.Next != null)
                {
                    var newFragment = new CilFragment(current.Value);

                    if (i != 0)
                    {
                        var lastInstr = newFragment.Last();
                        // Convert to switch
                        var converted = false;
                        fi.TryGetValue(lastInstr, out var info);

                        if (lastInstr.IsBr())
                        {
                            // Unconditional
                            var target = (Instruction)lastInstr.Operand;
                            if (info.ReferencedBy.Count == 0 && statementKeys.TryGetValue(target, out var brKey))
                            {
                                var targetKey = _predicate?.GetSwitchKey(brKey) ?? brKey;
                                var unkSrc    = HasUnknownSource(newFragment);

                                newFragment.Instructions.RemoveAt(newFragment.Instructions.Count - 1);

                                if (unkSrc)
                                {
                                    newFragment.Add(Instruction.Create(OpCodes.Ldc_I4, targetKey));
                                }
                                else
                                {
                                    var thisKey = key[i];
                                    var r       = rng.NextInt32();
                                    newFragment.Add(Instruction.Create(OpCodes.Ldloc, _local));
                                    newFragment.Add(Instruction.CreateLdcI4(r));
                                    newFragment.Add(Instruction.Create(OpCodes.Mul));
                                    newFragment.Add(Instruction.Create(OpCodes.Ldc_I4, (thisKey * r) ^ targetKey));
                                    newFragment.Add(Instruction.Create(OpCodes.Xor));
                                }

                                _context.AddJump(newFragment, switchHdrSecond, false);
                                operands[keyId[i]] = newFragment.First;
                                converted          = true;
                            }
                        }
                        else if (lastInstr.IsConditionalBranch())
                        {
                            // Conditional
                            var target = (Instruction)lastInstr.Operand;
                            if (info.ReferencedBy.Count == 0 && statementKeys.TryGetValue(target, out var brKey))
                            {
                                var unkSrc  = HasUnknownSource(newFragment);
                                var nextKey = key[i + 1];
                                var condBr  = newFragment.Last().OpCode;
                                newFragment.Instructions.RemoveAt(newFragment.Instructions.Count - 1);

                                if (rng.NextBoolean())
                                {
                                    condBr = DnextFactory.InverseBranch(condBr);
                                    var tmp = brKey;
                                    brKey   = nextKey;
                                    nextKey = tmp;
                                }

                                var thisKey = key[i];
                                int r = 0, xorKey = 0;
                                if (!unkSrc)
                                {
                                    r      = rng.NextInt32();
                                    xorKey = thisKey * r;
                                }

                                var brKeyInstr =
                                    Instruction.CreateLdcI4(xorKey ^ (_predicate?.GetSwitchKey(brKey) ?? brKey));
                                var nextKeyInstr =
                                    Instruction.CreateLdcI4(xorKey ^ (_predicate?.GetSwitchKey(nextKey) ?? nextKey));
                                var pop = Instruction.Create(OpCodes.Pop);

                                newFragment.Add(Instruction.Create(condBr, brKeyInstr));
                                newFragment.Add(nextKeyInstr);
                                newFragment.Add(Instruction.Create(OpCodes.Dup));
                                newFragment.Add(Instruction.Create(OpCodes.Br, pop));
                                newFragment.Add(brKeyInstr);
                                newFragment.Add(Instruction.Create(OpCodes.Dup));
                                newFragment.Add(pop);

                                if (!unkSrc)
                                {
                                    newFragment.Add(Instruction.Create(OpCodes.Ldloc, _local));
                                    newFragment.Add(Instruction.CreateLdcI4(r));
                                    newFragment.Add(Instruction.Create(OpCodes.Mul));
                                    newFragment.Add(Instruction.Create(OpCodes.Xor));
                                }

                                _context.AddJump(newFragment, switchHdrSecond, false);
                                operands[keyId[i]] = newFragment.First;
                                converted          = true;
                            }
                        }

                        if (!converted)
                        {
                            // Normal

                            var targetKey = _predicate?.GetSwitchKey(key[i + 1]) ?? key[i + 1];
                            if (!HasUnknownSource(newFragment))
                            {
                                var thisKey = key[i];
                                var r       = rng.NextInt32();
                                newFragment.Add(Instruction.Create(OpCodes.Ldloc, _local));
                                newFragment.Add(Instruction.CreateLdcI4(r));
                                newFragment.Add(Instruction.Create(OpCodes.Mul));
                                newFragment.Add(Instruction.Create(OpCodes.Ldc_I4, (thisKey * r) ^ targetKey));
                                newFragment.Add(Instruction.Create(OpCodes.Xor));
                            }
                            else
                            {
                                newFragment.Add(Instruction.Create(OpCodes.Ldc_I4, targetKey));
                            }

                            _context.AddJump(newFragment, switchHdrSecond, false);
                            operands[keyId[i]] = newFragment.First;
                        }
                    }
                    else
                    {
                        operands[keyId[i]] = switchHdr.First;
                    }

                    current.Value = newFragment;
                    current       = current.Next;
                    i++;
                }

                operands[keyId[i]]  = current.Value.First;
                switchInstr.Operand = operands;

                var first = fragments.First.Value;

                fragments.RemoveFirst();
                var last = fragments.Last.Value;

                fragments.RemoveLast();

                var newStatements = fragments.ToList();

                newStatements.Shuffle(rng);

                block.Fragment.Reset(first.Concat(switchHdr).Concat(newStatements.SelectMany(s => s)).Concat(last));
            }
示例#11
0
        protected override void Handle(NetfuserEvent ev)
        {
            var ns = Context.Plugin <INaming>();

            switch (ev)
            {
            case NetfuserEvent.ResourceMapped cre:
                var rm = cre.Mapping;
                if (rm.SourceModule != null && rm.Source.ResourceType == ResourceType.Embedded)
                {
                    var typeName = ParseName(rm.Source.Name);
                    if (typeName != null)
                    {
                        _bySourceType.Add(DnextFactory.NewTypeKey(rm.SourceModule, typeName),
                                          new Res {
                            Resource = (EmbeddedResource)rm.Target
                        });
                    }
                    ns.Preserve(rm);
                }

                break;

            case NameManglerEvent.GenerateName stnre:
                if (stnre.Options is NameGenerator.Encoded enc && stnre.Source is TypeDef td)
                {
                    if (_bySourceType.TryGetValue(td.CreateKey(), out _))
                    {
                        enc.Dictionary = ManglerCharsets.Latin;
                        // before we generate new name for this type (which is going to be used to name our resource,
                        // we need to make sure that it won't clash with any other type that has attached resource
                        stnre.Avoid(BuildTypeNamesToAvoid());
                    }
                }

                break;

            case NetfuserEvent.TypeSkeletonsImported ite:
                foreach (var kv in _bySourceType)
                {
                    if (Context.MappedTypes.TryGetValue(kv.Key, out var mapping))
                    {
                        kv.Value.TargetType    = mapping.Target;
                        kv.Value.Resource.Name = mapping.Target.FullName + Suffix;
                    }
                }

                break;

            case StringManglerEvent.WillMangle wme:
                if (wme.Method.ReturnType.FullName == typeof(System.Resources.ResourceManager).FullName &&
                    wme.Method.Body != null &&
                    _bySourceType.TryGetValue(wme.Method.DeclaringType.CreateKey(), out var r) &&
                    wme.String == wme.Method.DeclaringType.FullName)
                {
                    wme.String = r.TargetType?.FullName;
                    _bySourceType.Remove(wme.Method.DeclaringType.CreateKey());
                }
                break;

            case NetfuserEvent.CilBodyBuilding cme:
                if (cme.Source.ReturnType.FullName == typeof(System.Resources.ResourceManager).FullName &&
                    cme.Source.Body != null &&
                    _bySourceType.TryGetValue(cme.Source.DeclaringType.CreateKey(), out var rr) &&
                    rr.TargetType != null)
                {
                    var instr = cme.Fragment.Instructions.FirstOrDefault(i =>
                                                                         i.OpCode == OpCodes.Ldstr && (string)i.Operand == cme.Source.DeclaringType.FullName);
                    if (instr != null)
                    {
                        instr.Operand = rr.TargetType.FullName;
                    }
                }

                break;
            }
        }
示例#12
0
 /// <summary>
 /// This runs block parser on the target method body and returns parsed blocks.
 /// See <see cref="DnextFactory.ParseBlocks"/> for details
 /// </summary>
 /// <returns>parsed blocks</returns>
 public Block.Root ParseBlocks() => DnextFactory.ParseBlocks(Fragment.Instructions, ExceptionHandlers);
示例#13
0
 internal VTablePlugin(IContextImpl context)
     : base(context)
 {
     VTables = DnextFactory.NewVTables();
 }
        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);
        }