protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.TypeSkeletonsImported tsi: foreach (var tm in Context.MappedTypes.Values) { GetInjectableType(tm); } Context.Fire(new FeatureInjectorEvent.HaveInjectableTypes(Context)); break; case NetfuserEvent.InjectMembers ime: var it = PropInjectable[ime.TypeMapping]; if (it != null && it != NonInjectableType) { foreach (var flag in it.Flags.Values) { ime.Add(flag.Field); if (flag.Ctor == null && (it.Ctors.Count == 0 || Rng.NextBoolean())) { ime.Add(CreateFlagCtor(flag, s => !ime.HasInstanceCtor(s))); } } } break; case NetfuserEvent.CilBodyBuilding me: it = PropInjectable[me.TypeMapping]; var features = it.Flags.Values.SelectMany(f => f.Features) .Where(f => f.Method.Method == me.Source).ToList(); if (features.Count == 0) { break; } var emitter = me.GetEmitter(); var returns = ScanReturns(me); var mc = me.Fragment.First; foreach (var feature in features) { Logger.Debug($"insertion for {me.Target.Name} at {mc}"); using (emitter.BeginInsertion(mc, 0, true)) { feature.EmitChecker(emitter, Rng, mc); feature.Emit(me.Target, emitter, Rng); EmitEpilogue(emitter, feature, me, returns); mc = emitter.CurrentFragment.First; } } emitter.Commit(); break; } }
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; } }
protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.Initialize _: _seed = Context.Fire(new RngEvent.Create(Context, null) { Seed = Guid.NewGuid().ToString() }).Seed; break; } }
protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.MethodImported mi: var method = mi.Target; if (!method.HasBody) { break; } using (var context = new CFMangleContext(this, method, mi.Importer)) context.Run(); break; } }
protected override void Handle(NetfuserEvent ev) { switch (ev) { case FeatureInjectorEvent.HaveInjectableTypes tsi: _feature = new ValueManglingFeature(Context.TargetModule.CorLibTypes.Int32); var q = Math.Max(Context.MappedTypes.Count / 100, Rng.NextInt32(50, 100)); foreach (var node in _finj.Rate(_feature).OrderByDescending(r => r.Score) .SelectMany(ToNodes).Take(q)) { _demanglers.Add(node); } break; } }
protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.Complete ce: var ctx = (IContextImpl)ce.Context; var opt = new dnlib.DotNet.Writer.ModuleWriterOptions(ctx.TargetModule) { WritePdb = ctx.MainSourceModule.PdbState != null }; if (!_dest.Exists) { _dest.Create(); } var mainDestPath = Path.Combine(_dest.FullName, ctx.MainSourceModule.Name); ctx.TargetModule.Write(mainDestPath, opt); if (ctx.SourceModules.TryGetValue(ModuleTreat.Copy, out var toCopy)) { foreach (var mod in toCopy) { File.Copy(mod.Location, Path.Combine(_dest.FullName, mod.Name), true); } } var srcFolder = Path.GetDirectoryName(ctx.MainSourceModule.Location); var srcNameMinusExt = Path.GetFileNameWithoutExtension(ctx.MainSourceModule.Location); var srcPathMinusExt = Path.Combine(srcFolder, srcNameMinusExt); var dstPathMinusExt = Path.Combine(_dest.FullName, Path.GetFileNameWithoutExtension(ctx.MainSourceModule.Name)); foreach (var suffix in ConfigSuffixes) { var cfgPath = srcPathMinusExt + suffix; if (File.Exists(cfgPath)) { File.Copy(cfgPath, dstPathMinusExt + suffix, true); } } ctx.MainSourceModule.Assembly.TryGetOriginalTargetFrameworkAttribute(out var fw, out var ver, out _); if (fw == ".NETCoreApp" && ver.Major >= 3 && !ctx.MainSourceModule.Name.EndsWith(ExeSuffix)) { var launcher = srcPathMinusExt + ExeSuffix; if (File.Exists(launcher)) { File.Copy(launcher, dstPathMinusExt + ExeSuffix, true); } } break; } }
protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.WillMergeModules _: var ctx = Context; var jsonDeps = Path.Combine(Path.GetDirectoryName(ctx.MainSourceModule.Location), Path.GetFileNameWithoutExtension(ctx.MainSourceModule.Location) + ".deps.json"); if (!File.Exists(jsonDeps)) { break; } using (var r = new DependencyContextJsonReader()) using (var fs = File.OpenRead(jsonDeps)) _deps = r.Read(fs); break; } }
protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.Complete ce: var dest = _dest; if (!Path.IsPathRooted(dest) && Context.OutputFolder != null) { if (!Context.OutputFolder.Exists) { Context.OutputFolder.Create(); } dest = Path.Combine(Context.OutputFolder.FullName, dest); } using (var writer = new StreamWriter(dest)) WriteXml(writer); break; } }
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; } }
protected abstract void Handle(NetfuserEvent ev);
protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.Initialize _: var building = _options.Building; if (building == Building.No) { break; } if (building == Building.CleanBuild) { foreach (var p in _allProjects.Values) { p.RemoveOutput(); } building = Building.Build; } Logger.Info($"building {_root.CsprojPath}"); if (Options.AutoIncrementTargetAssemblyBuildNumber) { _root.IncrementBuildNumber(); } var buildOptions = new List <string> { _root.CsprojPath }; string cmd = null; var cfg = BuildConfiguration; switch (building) { case Building.Build: cmd = "Build"; break; case Building.Rebuild: cmd = "Rebuild"; break; } var logpath = Path.Combine(Path.GetDirectoryName(_root.CsprojPath), "msbuild.log"); switch (_buildTool) { case BuildTool.Devenv: buildOptions.Add("/" + cmd); buildOptions.Add("/" + cfg); buildOptions.Add("/out " + logpath); break; case BuildTool.Msbuild: buildOptions.Add("-t:" + cmd); buildOptions.Add("-p:Configuration=" + cfg); buildOptions.Add("-restore"); buildOptions.Add("-fileLogger"); buildOptions.Add("-fileLoggerParameters:LogFile=" + logpath); if (_options.MaxCpuCount > 0) { buildOptions.Add("/maxcpucount:" + _options.MaxCpuCount); } break; } var be = new ProjectEvents.Build(Context, _root) { BuilderPath = _builderPath, BuilderArguments = buildOptions, }; Context.Fire(be); var res = Utils.RunProcess(be.BuilderPath, be.BuilderArguments.ToArray()); if (res.ExitCode != 0) { Context.Error("build failed"); } break; case NetfuserEvent.LoadSourceModules lsm: lsm.Sources.Add(ModuleDefMD.Load(_root.AssemblyPath, Context.ModuleContext)); break; case NetfuserEvent.ResolveSourceModules rsm: var asmName = rsm.Module.Assembly.Name; if (_allPackageReferences.Contains(asmName) && rsm.Treat != ModuleTreat.Ignore) { rsm.Treat = ModuleTreat.Embed; } break; } }
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; } }
protected override void Handle(NetfuserEvent ev) { switch (ev) { case NetfuserEvent.TypeSkeletonsImported tsi: _allDemanglers = Context.Plugins <IStringMangleMethod>(); if (_allDemanglers.Count == 0) { break; } var strings = new Dictionary <string, StringPieces>(); foreach (var tm in Context.MappedTypes.Values) { foreach (var m in tm.Source.Methods) { var mBody = m.Body; if (mBody != null) { foreach (var i in mBody.Instructions.Where(i => i.OpCode.Code == Code.Ldstr) ) { var s = Context.Fire(new StringManglerEvent.WillMangle(Context, tm, m, i)).String; if (!string.IsNullOrEmpty(s)) { if (!strings.TryGetValue(s, out var p)) { strings.Add(s, p = new StringPieces()); } p.References.Add(new InstrRef(m, i)); } } } } } var splitter = Context.Plugin <IStringSplitter>(); if (splitter != null) { splitter.Split(strings); foreach (var kv in strings) { var pieces = kv.Value.Pieces; if (pieces != null) { string fault = null; if (pieces.Count == 1) { var value = pieces[0].Value; if (value != kv.Key) { fault = value; } } else if (pieces.Count > 0) { var sb = new StringBuilder(); foreach (var piece in pieces) { sb.Append(piece.Value); } if (sb.ToString() != kv.Key) { fault = sb.ToString(); } } if (fault != null) { throw Context.Error($"string splitter faulted: {fault}!={kv.Key}"); } if (pieces.Any(p => string.IsNullOrEmpty(p.Value))) { throw Context.Error($"string splitter returned empty string piece for {kv.Key}"); } } else { kv.Value.Set(new[] { new StringPiece(kv.Key) }); } } } else { foreach (var kv in strings) // prefer to do it here rather than below, because it's exact string->string correspondence here, and below we may create unnecesary duplicates of StringPieces for the same strings { kv.Value.Set(new[] { new StringPiece(kv.Key) }); } } // group strings by method and referencing ldstrs foreach (var r in strings.Values) { foreach (var ir in r.References) { if (!_byMethod.TryGetValue(ir.Method, out var srl)) { _byMethod.Add(ir.Method, srl = new Dictionary <Instruction, IReadOnlyList <StringPiece> >()); } srl.Add(ir.Instruction, r.Pieces); } } strings.Clear(); break; case NetfuserEvent.CilBodyBuilding bb: if (!_byMethod.TryGetValue(bb.Source, out var list)) { break; } _byMethod.Remove(bb.Source); var il = bb.GetEmitter(); foreach (var kv in list) { var maxIter = kv.Value.Count * 100; using (il.BeginInsertion(bb.Map(kv.Key))) using (var sdmc = new StringMangleContext(this, bb.Source, il, kv.Value)) { while (!sdmc.IsEmpty) { var demangler = _allDemanglers.RandomElementOrDefault(Rng); if (demangler != null) // theoretically all demanglers may refuse on this attempt, but some may accept on the next, as their decision may be random { sdmc.Use(demangler); } if (maxIter-- <= 0) { throw Context.Error("could not emit demangler for " + sdmc); } } } } il.Commit(); break; } }