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; } }
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()); } } } }
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); }
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(); } } }
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(); } }
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; } }