static void BeginModule(DotProtectContext context) { context.Logger.InfoFormat("Processing module '{0}'...", context.CurrentModule.Name); context.CurrentModuleWriterListener = new ModuleWriterListener(); context.CurrentModuleWriterListener.OnWriterEvent += (sender, e) => context.CheckCancellation(); context.CurrentModuleWriterOptions = new ModuleWriterOptions(context.CurrentModule, context.CurrentModuleWriterListener); CopyPEHeaders(context.CurrentModuleWriterOptions.PEHeadersOptions, context.CurrentModule); if (!context.CurrentModule.IsILOnly || context.CurrentModule.VTableFixups != null) { context.RequestNative(); } var snKey = context.Annotations.Get <StrongNameKey>(context.CurrentModule, Marker.SNKey); context.CurrentModuleWriterOptions.InitializeStrongNameSigning(context.CurrentModule, snKey); foreach (TypeDef type in context.CurrentModule.GetTypes()) { foreach (MethodDef method in type.Methods) { if (method.Body != null) { method.Body.Instructions.SimplifyMacros(method.Body.Variables, method.Parameters); } } } }
/// <inheritdoc /> protected internal override MarkerResult MarkProject(DotProtectProject proj, DotProtectContext context) { this.context = context; project = proj; extModules = new List <byte[]>(); if (proj.Packer != null) { if (!packers.ContainsKey(proj.Packer.Id)) { context.Logger.ErrorFormat("Cannot find packer with ID '{0}'.", proj.Packer.Id); throw new DotProtectception(null); } packer = packers[proj.Packer.Id]; packerParams = new Dictionary <string, string>(proj.Packer, StringComparer.OrdinalIgnoreCase); } var modules = new List <Tuple <ProjectModule, ModuleDefMD> >(); foreach (ProjectModule module in proj) { if (module.IsExternal) { extModules.Add(module.LoadRaw(proj.BaseDirectory)); continue; } ModuleDefMD modDef = module.Resolve(proj.BaseDirectory, context.Resolver.DefaultModuleContext); context.CheckCancellation(); context.Resolver.AddToCache(modDef); modules.Add(Tuple.Create(module, modDef)); } foreach (var module in modules) { context.Logger.InfoFormat("Loading '{0}'...", module.Item1.Path); Rules rules = ParseRules(proj, module.Item1, context); MarkModule(module.Item1, module.Item2, rules, module == modules[0]); context.Annotations.Set(module.Item2, RulesKey, rules); // Packer parameters are stored in modules if (packer != null) { ProtectionParameters.GetParameters(context, module.Item2)[packer] = packerParams; } } if (proj.Debug && proj.Packer != null) { context.Logger.Warn("Generated Debug symbols might not be usable with packers!"); } return(new MarkerResult(modules.Select(module => module.Item2).ToList(), packer, extModules)); }
/// <summary> /// Execute the specified pipeline stage with pre-processing and post-processing. /// </summary> /// <param name="stage">The pipeline stage.</param> /// <param name="func">The stage function.</param> /// <param name="targets">The target list of the stage.</param> /// <param name="context">The working context.</param> internal void ExecuteStage(PipelineStage stage, Action <DotProtectContext> func, Func <IList <IDnlibDef> > targets, DotProtectContext context) { foreach (ProtectionPhase pre in preStage[stage]) { context.CheckCancellation(); context.Logger.DebugFormat("Executing '{0}' phase...", pre.Name); pre.Execute(context, new ProtectionParameters(pre.Parent, Filter(context, targets(), pre))); } context.CheckCancellation(); func(context); context.CheckCancellation(); foreach (ProtectionPhase post in postStage[stage]) { context.Logger.DebugFormat("Executing '{0}' phase...", post.Name); post.Execute(context, new ProtectionParameters(post.Parent, Filter(context, targets(), post))); context.CheckCancellation(); } }
/// <summary> /// Adds plugins in the assembly to the protection list. /// </summary> /// <param name="context">The working context.</param> /// <param name="protections">The working list of protections.</param> /// <param name="packers">The working list of packers.</param> /// <param name="components">The working list of components.</param> /// <param name="asm">The assembly.</param> protected static void AddPlugins( DotProtectContext context, IList <Protection> protections, IList <Packer> packers, IList <DotProtectComponent> components, Assembly asm) { foreach (var module in asm.GetLoadedModules()) { foreach (var i in module.GetTypes()) { if (i.IsAbstract || !HasAccessibleDefConstructor(i)) { continue; } if (typeof(Protection).IsAssignableFrom(i)) { try { protections.Add((Protection)Activator.CreateInstance(i)); } catch (Exception ex) { context.Logger.ErrorException("Failed to instantiate protection '" + i.Name + "'.", ex); } } else if (typeof(Packer).IsAssignableFrom(i)) { try { packers.Add((Packer)Activator.CreateInstance(i)); } catch (Exception ex) { context.Logger.ErrorException("Failed to instantiate packer '" + i.Name + "'.", ex); } } else if (typeof(DotProtectComponent).IsAssignableFrom(i)) { try { components.Add((DotProtectComponent)Activator.CreateInstance(i)); } catch (Exception ex) { context.Logger.ErrorException("Failed to instantiate component '" + i.Name + "'.", ex); } } } } context.CheckCancellation(); }
/// <summary> /// Runs the engine. /// </summary> /// <param name="parameters">The parameters.</param> /// <param name="token">The cancellation token.</param> static void RunInternal(DotProtectParameters parameters, CancellationToken token) { // 1. Setup context var context = new DotProtectContext(); context.Logger = parameters.GetLogger(); context.Project = parameters.Project.Clone(); context.PackerInitiated = parameters.PackerInitiated; context.token = token; PrintInfo(context); bool ok = false; try { var asmResolver = new AssemblyResolver(); asmResolver.EnableTypeDefCache = true; asmResolver.DefaultModuleContext = new ModuleContext(asmResolver); context.Resolver = asmResolver; context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, parameters.Project.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar); context.OutputDirectory = Path.Combine(parameters.Project.BaseDirectory, parameters.Project.OutputDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar); foreach (string probePath in parameters.Project.ProbePaths) { asmResolver.PostSearchPaths.Insert(0, Path.Combine(context.BaseDirectory, probePath)); } context.CheckCancellation(); Marker marker = parameters.GetMarker(); // 2. Discover plugins context.Logger.Debug("Discovering plugins..."); IList <Protection> prots; IList <Packer> packers; IList <DotProtectComponent> components; PluginFinder.Find(out prots, out packers, out components); context.Logger.InfoFormat("Discovered {0} protections, {1} packers.", prots.Count, packers.Count); context.CheckCancellation(); // 3. Resolve dependency context.Logger.Debug("Resolving component dependency..."); try { var resolver = new DependencyResolver(prots); prots = resolver.SortDependency(); } catch (CircularDependencyException ex) { context.Logger.ErrorException("", ex); throw new DotProtectception(ex); } components.Insert(0, new CoreComponent(parameters, marker)); foreach (Protection prot in prots) { components.Add(prot); } foreach (Packer packer in packers) { components.Add(packer); } context.CheckCancellation(); // 4. Load modules context.Logger.Info("Loading input modules..."); marker.Initalize(prots, packers); MarkerResult markings = marker.MarkProject(parameters.Project, context); context.Modules = new ModuleSorter(markings.Modules).Sort().ToList().AsReadOnly(); foreach (var module in context.Modules) { module.EnableTypeDefFindCache = false; } context.OutputModules = Enumerable.Repeat <byte[]>(null, context.Modules.Count).ToArray(); context.OutputSymbols = Enumerable.Repeat <byte[]>(null, context.Modules.Count).ToArray(); context.OutputPaths = Enumerable.Repeat <string>(null, context.Modules.Count).ToArray(); context.Packer = markings.Packer; context.ExternalModules = markings.ExternalModules; context.CheckCancellation(); // 5. Initialize components context.Logger.Info("Initializing..."); foreach (DotProtectComponent comp in components) { try { comp.Initialize(context); } catch (Exception ex) { context.Logger.ErrorException("Error occured during initialization of '" + comp.Name + "'.", ex); throw new DotProtectception(ex); } context.CheckCancellation(); } context.CheckCancellation(); // 6. Build pipeline context.Logger.Debug("Building pipeline..."); var pipeline = new ProtectionPipeline(); context.Pipeline = pipeline; foreach (DotProtectComponent comp in components) { comp.PopulatePipeline(pipeline); } context.CheckCancellation(); //7. Run pipeline RunPipeline(pipeline, context); ok = true; } catch (AssemblyResolveException ex) { context.Logger.ErrorException("Failed to resolve an assembly, check if all dependencies are present in the correct version.", ex); PrintEnvironmentInfo(context); } catch (TypeResolveException ex) { context.Logger.ErrorException("Failed to resolve a type, check if all dependencies are present in the correct version.", ex); PrintEnvironmentInfo(context); } catch (MemberRefResolveException ex) { context.Logger.ErrorException("Failed to resolve a member, check if all dependencies are present in the correct version.", ex); PrintEnvironmentInfo(context); } catch (IOException ex) { context.Logger.ErrorException("An IO error occurred, check if all input/output locations are readable/writable.", ex); } catch (OperationCanceledException) { context.Logger.Error("Operation cancelled."); } catch (DotProtectception ex) { // Exception is already handled/logged, so just ignore and report failure } catch (Exception ex) { context.Logger.ErrorException("Unknown error occurred.", ex); } finally { if (context.Resolver != null) { context.Resolver.Clear(); } context.Logger.Finish(ok); } }
/// <summary> /// Loads the assembly and marks the project. /// </summary> /// <param name="proj">The project.</param> /// <param name="context">The working context.</param> /// <returns><see cref="MarkerResult" /> storing the marked modules and packer information.</returns> protected internal virtual MarkerResult MarkProject(DotProtectProject proj, DotProtectContext context) { Packer packer = null; Dictionary <string, string> packerParams = null; if (proj.Packer != null) { if (!packers.ContainsKey(proj.Packer.Id)) { context.Logger.ErrorFormat("Cannot find packer with ID '{0}'.", proj.Packer.Id); throw new DotProtectception(null); } if (proj.Debug) { context.Logger.Warn("Generated Debug symbols might not be usable with packers!"); } packer = packers[proj.Packer.Id]; packerParams = new Dictionary <string, string>(proj.Packer, StringComparer.OrdinalIgnoreCase); } var modules = new List <Tuple <ProjectModule, ModuleDefMD> >(); var extModules = new List <byte[]>(); foreach (ProjectModule module in proj) { if (module.IsExternal) { extModules.Add(module.LoadRaw(proj.BaseDirectory)); continue; } ModuleDefMD modDef = module.Resolve(proj.BaseDirectory, context.Resolver.DefaultModuleContext); context.CheckCancellation(); if (proj.Debug) { modDef.LoadPdb(); } context.Resolver.AddToCache(modDef); modules.Add(Tuple.Create(module, modDef)); } foreach (var module in modules) { context.Logger.InfoFormat("Loading '{0}'...", module.Item1.Path); Rules rules = ParseRules(proj, module.Item1, context); context.Annotations.Set(module.Item2, SNKey, LoadSNKey(context, module.Item1.SNKeyPath == null ? null : Path.Combine(proj.BaseDirectory, module.Item1.SNKeyPath), module.Item1.SNKeyPassword)); context.Annotations.Set(module.Item2, RulesKey, rules); foreach (IDnlibDef def in module.Item2.FindDefinitions()) { ApplyRules(context, def, rules); context.CheckCancellation(); } // Packer parameters are stored in modules if (packerParams != null) { ProtectionParameters.GetParameters(context, module.Item2)[packer] = packerParams; } } return(new MarkerResult(modules.Select(module => module.Item2).ToList(), packer, extModules)); }