Esempio n. 1
0
        protected override bool Process(AssemblyStitcherContext context)
        {
            try
            {
                Logging.Write("Assembly at {0}", context.AssemblyPath);
                bool processed   = false;
                var  directives  = LoadDirectives();
                var  disposables = new List <IDisposable>();
                ModuleWritten += delegate
                {
                    foreach (var disposable in disposables)
                    {
                        disposable.Dispose();
                    }
                };
                foreach (var reference in context.Dependencies)
                {
                    var assemblyFile = new AssemblyFile(reference, context.AssemblyPath);
                    var action       = GetAction(assemblyFile, directives, context.Configuration);
                    switch (action)
                    {
                    case BlobAction.Embed:
                        Embed(context.Module, assemblyFile);
                        processed = true;
                        break;

                    case BlobAction.Merge:
                        disposables.Add(Merge(context.Module, assemblyFile));
                        processed = true;
                        break;

                    case null:
                        if (context.Configuration == "Debug")
                        {
                            Logging.Write("Assembly {0} ({1}) excluded from process (no matching action at all)", GetReferenceName(reference),
                                          reference.IsPrivate ? "private" : "non-private");
                        }
                        break;

                    case BlobAction.None:
                        if (context.Configuration == "Debug")
                        {
                            Logging.Write("Assembly {0} ({1}) excluded from process", GetReferenceName(reference), reference.IsPrivate ? "private" : "non-private");
                        }
                        break;
                    }
                }

                if (processed)
                {
                    EmbedLoader(context.Module, context.TaskAssemblyPath);
                }
                return(processed);
            }
            catch (Exception e)
            {
                Logging.WriteError("Error while blobbing: {0}", e);
            }
            return(false);
        }
Esempio n. 2
0
 private void Embed(ModuleDefMD2 targetModule, AssemblyFile assemblyFile)
 {
     using (var moduleManager = new ModuleManager(assemblyFile.Path, false, null))
     {
         var baseName = GetBaseName(moduleManager.Module);
         Logging.Write("Embedding {0} from {1}", baseName, assemblyFile.Path);
         var gzippedAssembly = GetGZippedAssembly(assemblyFile.Path);
         targetModule.Resources.Add(new EmbeddedResource(Loader.GetEmbeddedAssemblyResourceName(baseName), gzippedAssembly));
     }
     assemblyFile.DeleteIfLocal();
 }
Esempio n. 3
0
        /// <summary>
        /// Gets the action.
        /// </summary>
        /// <param name="assemblyReference">The assembly reference.</param>
        /// <param name="directives">The directives.</param>
        /// <param name="configuration">The configuration.</param>
        /// <returns></returns>
        private static BlobAction?GetAction(AssemblyFile assemblyReference, IList <BlobDirective> directives, string configuration)
        {
            BlobAction?action = null;

            foreach (var directive in directives)
            {
                var directiveAction = directive.Matches(assemblyReference.Reference, configuration);
                if (directiveAction.HasValue)
                {
                    action = directiveAction.Value;
                }
            }
            return(action);
        }
Esempio n. 4
0
        /// <summary>
        /// Merges the specified target module.
        /// </summary>
        /// <param name="targetModule">The target module.</param>
        /// <param name="assemblyFile">The assembly file.</param>
        private IDisposable Merge(ModuleDefMD2 targetModule, AssemblyFile assemblyFile)
        {
            var moduleManager = new ModuleManager(assemblyFile.Path, false, null);

            {
                var baseName = GetBaseName(moduleManager.Module);
                Logging.Write("Merging   {0}", baseName);
                targetModule.Resources.Add(new EmbeddedResource(Loader.GetMergedAssemblyResourceName(baseName), new byte[0]));

                var allReferenceTypes = moduleManager.Module.Types.ToArray();
                moduleManager.Module.Types.Clear();
                foreach (var referenceType in allReferenceTypes)
                {
                    // <Module> is handled differently
                    if (referenceType.Name == "<Module>")
                    {
                        var referenceCCtor = referenceType.FindStaticConstructor();
                        // if there is a cctor in ref
                        if (referenceCCtor != null)
                        {
                            // if no target <Module> (I don't think this is even possible), then the current <Module> is copied
                            var targetModuleModuleType = targetModule.Find("<Module>", true);
                            if (targetModuleModuleType == null)
                            {
                                targetModule.Types.Add(referenceType);
                            }
                            else
                            {
                                // otherwise the ref cctor is renamed, inserted as a simple method and called
                                var targetModuleCctor = targetModuleModuleType.FindOrCreateStaticConstructor();
                                // 1. renaming
                                referenceCCtor.Name        = referenceCCtor.Name + "/" + moduleManager.Module.Name;
                                referenceCCtor.Attributes &= ~MethodAttributes.SpecialName;
                                // 2. adding
                                targetModuleModuleType.Methods.Add(referenceCCtor);
                                // 3. calling
                                targetModuleCctor.Body.Instructions.Add(new Instruction(OpCodes.Call, targetModule.Import(referenceCCtor)));
                            }
                        }
                    }
                    else
                    {
                        // other case: simply move the type

                        // check if there is a conflict, and if there is, change new type name
                        var existingType = targetModule.Find(referenceType.FullName, true);
                        if (existingType != null)
                        {
                            referenceType.Name = GetMergedName(referenceType, moduleManager.Module);
                        }
                        // and add the type
                        targetModule.Types.Add(referenceType);
                    }
                }

                // TODO: resources
                // TODO: attributes?

                var relocator = new ModuleRelocator(moduleManager.Module, targetModule);
                relocator.Relocate();
            }
            assemblyFile.DeleteIfLocal();
            return(moduleManager);
        }