/// <summary> /// Marks the member definition. /// </summary> /// <param name="member">The member definition.</param> /// <param name="context">The working context.</param> protected internal virtual void MarkMember(IDnlibDef member, DotProtectContext context) { ModuleDef module = ((IMemberRef)member).Module; var rules = context.Annotations.Get <Rules>(module, RulesKey); ApplyRules(context, member, rules); }
static void EndModule(DotProtectContext context) { foreach (var module in context.Modules) { foreach (var type in module.Types) { for (int i = type.CustomAttributes.Count - 1; i > -1; --i) { var attribute = type.CustomAttributes[i]; if (attribute.AttributeType.FullName == "System.Diagnostics.DebuggerDisplayAttribute") { type.CustomAttributes.Remove(attribute); } } } } string output = context.Modules[context.CurrentModuleIndex].Location; if (output != null) { if (!Path.IsPathRooted(output)) { output = Path.Combine(Environment.CurrentDirectory, output); } output = CoreUtils.GetRelativePath(output, context.BaseDirectory); } else { output = context.CurrentModule.Name; } context.OutputPaths[context.CurrentModuleIndex] = output; }
static void WriteModule(DotProtectContext context) { context.Logger.InfoFormat("Writing module '{0}'...", context.CurrentModule.Name); MemoryStream pdb = null, output = new MemoryStream(); if (context.CurrentModule.PdbState != null) { pdb = new MemoryStream(); context.CurrentModuleWriterOptions.WritePdb = true; context.CurrentModuleWriterOptions.PdbFileName = Path.ChangeExtension(Path.GetFileName(context.OutputPaths[context.CurrentModuleIndex]), "pdb"); context.CurrentModuleWriterOptions.PdbStream = pdb; } if (context.CurrentModuleWriterOptions is ModuleWriterOptions) { context.CurrentModule.Write(output, (ModuleWriterOptions)context.CurrentModuleWriterOptions); } else { context.CurrentModule.NativeWrite(output, (NativeModuleWriterOptions)context.CurrentModuleWriterOptions); } context.CurrentModuleOutput = output.ToArray(); if (context.CurrentModule.PdbState != null) { context.CurrentModuleSymbol = pdb.ToArray(); } }
/// <summary> /// Retrieves the available protection plugins. /// </summary> /// <param name="context">The working context.</param> /// <param name="protections">A list of resolved protections.</param> /// <param name="packers">A list of resolved packers.</param> /// <param name="components">A list of resolved components.</param> public void GetPlugins(DotProtectContext context, out IList <Protection> protections, out IList <Packer> packers, out IList <DotProtectComponent> components) { protections = new List <Protection>(); packers = new List <Packer>(); components = new List <DotProtectComponent>(); GetPluginsInternal(context, protections, packers, components); }
/// <summary> /// Loads the Strong Name Key at the specified path with a optional password. /// </summary> /// <param name="context">The working context.</param> /// <param name="path">The path to the key.</param> /// <param name="pass"> /// The password of the certificate at <paramref name="path" /> if /// it is a pfx file; otherwise, <c>null</c>. /// </param> /// <returns>The loaded Strong Name Key.</returns> public static StrongNameKey LoadSNKey(DotProtectContext context, string path, string pass) { if (path == null) { return(null); } try { if (pass != null) //pfx { // http://stackoverflow.com/a/12196742/462805 var cert = new X509Certificate2(); cert.Import(path, pass, X509KeyStorageFlags.Exportable); var rsa = cert.PrivateKey as RSACryptoServiceProvider; if (rsa == null) { throw new ArgumentException("RSA key does not present in the certificate.", "path"); } return(new StrongNameKey(rsa.ExportCspBlob(true))); } return(new StrongNameKey(path)); } catch (Exception ex) { context.Logger.ErrorException("Cannot load the Strong Name Key located at: " + path, ex); throw new DotProtectception(ex); } }
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); } } } }
/// <summary> /// Applies the rules to the target definition. /// </summary> /// <param name="context">The working context.</param> /// <param name="target">The target definition.</param> /// <param name="rules">The rules.</param> /// <param name="baseSettings">The base settings.</param> protected void ApplyRules(DotProtectContext context, IDnlibDef target, Rules rules, ProtectionSettings baseSettings = null) { var ret = baseSettings == null ? new ProtectionSettings() : new ProtectionSettings(baseSettings); foreach (var i in rules) { if (!(bool)i.Value.Evaluate(target)) { continue; } if (!i.Key.Inherit) { ret.Clear(); } FillPreset(i.Key.Preset, ret); foreach (var prot in i.Key) { if (prot.Action == SettingItemAction.Add) { ret[protections[prot.Id]] = new Dictionary <string, string>(prot, StringComparer.OrdinalIgnoreCase); } else { ret.Remove(protections[prot.Id]); } } } ProtectionParameters.SetParameters(context, target, ret); }
/// <summary> /// Parses the rules' patterns. /// </summary> /// <param name="proj">The project.</param> /// <param name="module">The module description.</param> /// <param name="context">The working context.</param> /// <returns>Parsed rule patterns.</returns> /// <exception cref="System.ArgumentException"> /// One of the rules has invalid pattern. /// </exception> protected Rules ParseRules(DotProtectProject proj, ProjectModule module, DotProtectContext context) { var ret = new Rules(); var parser = new PatternParser(); foreach (Rule rule in proj.Rules.Concat(module.Rules)) { try { ret.Add(rule, parser.Parse(rule.Pattern)); } catch (InvalidPatternException ex) { context.Logger.ErrorFormat("Invalid rule pattern: " + rule.Pattern + ".", ex); throw new DotProtectception(ex); } foreach (var setting in rule) { if (!protections.ContainsKey(setting.Id)) { context.Logger.ErrorFormat("Cannot find protection with ID '{0}'.", setting.Id); throw new DotProtectception(null); } } } return(ret); }
static void Pack(DotProtectContext context) { if (context.Packer != null) { context.Logger.Info("Packing..."); context.Packer.Pack(context, new ProtectionParameters(context.Packer, context.Modules.OfType <IDnlibDef>().ToList())); } }
/// <inheritdoc /> protected internal override void MarkMember(IDnlibDef member, DotProtectContext context) { ModuleDef module = ((IMemberRef)member).Module; var stack = context.Annotations.Get <ProtectionSettingsStack>(module, ModuleSettingsKey); using (stack.Apply(member, Enumerable.Empty <ProtectionSettingsInfo>())) return; }
/// <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)); }
/// <inheritdoc /> protected internal override void Initialize(DotProtectContext context) { context.Registry.RegisterService(_RandomServiceId, typeof(IRandomService), new RandomService(parameters.Project.Seed)); context.Registry.RegisterService(_MarkerServiceId, typeof(IMarkerService), new MarkerService(context, marker)); context.Registry.RegisterService(_TraceServiceId, typeof(ITraceService), new TraceService(context)); context.Registry.RegisterService(_RuntimeServiceId, typeof(IRuntimeService), new RuntimeService()); context.Registry.RegisterService(_CompressionServiceId, typeof(ICompressionService), new CompressionService(context)); context.Registry.RegisterService(_APIStoreId, typeof(IAPIStore), new APIStore(context)); }
protected internal override MarkerResult MarkProject(DotProtectProject proj, DotProtectContext context) { MarkerResult result = base.MarkProject(proj, context); foreach (ModuleDefMD module in result.Modules) { context.Annotations.Set(module, SNKey, snKey); } return(result); }
/// <summary> /// Runs the protection pipeline. /// </summary> /// <param name="pipeline">The protection pipeline.</param> /// <param name="context">The context.</param> static void RunPipeline(ProtectionPipeline pipeline, DotProtectContext context) { Func <IList <IDnlibDef> > getAllDefs = () => context.Modules.SelectMany(module => module.FindDefinitions()).ToList(); Func <ModuleDef, IList <IDnlibDef> > getModuleDefs = module => module.FindDefinitions().ToList(); context.CurrentModuleIndex = -1; pipeline.ExecuteStage(PipelineStage.Inspection, Inspection, () => getAllDefs(), context); var options = new ModuleWriterOptionsBase[context.Modules.Count]; var listeners = new ModuleWriterListener[context.Modules.Count]; for (int i = 0; i < context.Modules.Count; i++) { context.CurrentModuleIndex = i; context.CurrentModuleWriterOptions = null; context.CurrentModuleWriterListener = null; pipeline.ExecuteStage(PipelineStage.BeginModule, BeginModule, () => getModuleDefs(context.CurrentModule), context); pipeline.ExecuteStage(PipelineStage.ProcessModule, ProcessModule, () => getModuleDefs(context.CurrentModule), context); pipeline.ExecuteStage(PipelineStage.OptimizeMethods, OptimizeMethods, () => getModuleDefs(context.CurrentModule), context); pipeline.ExecuteStage(PipelineStage.EndModule, EndModule, () => getModuleDefs(context.CurrentModule), context); options[i] = context.CurrentModuleWriterOptions; listeners[i] = context.CurrentModuleWriterListener; } for (int i = 0; i < context.Modules.Count; i++) { context.CurrentModuleIndex = i; context.CurrentModuleWriterOptions = options[i]; context.CurrentModuleWriterListener = listeners[i]; pipeline.ExecuteStage(PipelineStage.WriteModule, WriteModule, () => getModuleDefs(context.CurrentModule), context); context.OutputModules[i] = context.CurrentModuleOutput; context.OutputSymbols[i] = context.CurrentModuleSymbol; context.CurrentModuleWriterOptions = null; context.CurrentModuleWriterListener = null; context.CurrentModuleOutput = null; context.CurrentModuleSymbol = null; } context.CurrentModuleIndex = -1; pipeline.ExecuteStage(PipelineStage.Debug, Debug, () => getAllDefs(), context); pipeline.ExecuteStage(PipelineStage.Pack, Pack, () => getAllDefs(), context); pipeline.ExecuteStage(PipelineStage.SaveModules, SaveModules, () => getAllDefs(), context); if (!context.PackerInitiated) { context.Logger.Info("Done."); } }
static void OptimizeMethods(DotProtectContext context) { foreach (TypeDef type in context.CurrentModule.GetTypes()) { foreach (MethodDef method in type.Methods) { if (method.Body != null) { method.Body.Instructions.OptimizeMacros(); } } } }
static void SaveModules(DotProtectContext context) { context.Resolver.Clear(); for (int i = 0; i < context.OutputModules.Count; i++) { string path = Path.GetFullPath(Path.Combine(context.OutputDirectory, context.OutputPaths[i])); string dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } context.Logger.DebugFormat("Saving to '{0}'...", path); File.WriteAllBytes(path, context.OutputModules[i]); } }
/// <summary> /// Returns only the targets with the specified type and used by specified component. /// </summary> /// <param name="context">The working context.</param> /// <param name="targets">List of targets.</param> /// <param name="phase">The component phase.</param> /// <returns>Filtered targets.</returns> static IList <IDnlibDef> Filter(DotProtectContext context, IList <IDnlibDef> targets, ProtectionPhase phase) { ProtectionTargets targetType = phase.Targets; IEnumerable <IDnlibDef> filter = targets; if ((targetType & ProtectionTargets.Modules) == 0) { filter = filter.Where(def => !(def is ModuleDef)); } if ((targetType & ProtectionTargets.Types) == 0) { filter = filter.Where(def => !(def is TypeDef)); } if ((targetType & ProtectionTargets.Methods) == 0) { filter = filter.Where(def => !(def is MethodDef)); } if ((targetType & ProtectionTargets.Fields) == 0) { filter = filter.Where(def => !(def is FieldDef)); } if ((targetType & ProtectionTargets.Properties) == 0) { filter = filter.Where(def => !(def is PropertyDef)); } if ((targetType & ProtectionTargets.Events) == 0) { filter = filter.Where(def => !(def is EventDef)); } if (phase.ProcessAll) { return(filter.ToList()); } return(filter.Where(def => { ProtectionSettings parameters = ProtectionParameters.GetParameters(context, def); Debug.Assert(parameters != null); if (parameters == null) { context.Logger.ErrorFormat("'{0}' not marked for obfuscation, possibly a bug.", def); throw new DotProtectception(null); } return parameters.ContainsKey(phase.Parent); }).ToList()); }
/// <summary> /// Obtains the value of a parameter of the specified target. /// </summary> /// <typeparam name="T">The type of the parameter value.</typeparam> /// <param name="context">The working context.</param> /// <param name="target">The protection target.</param> /// <param name="name">The name of the parameter.</param> /// <param name="defValue">Default value if the parameter does not exist.</param> /// <returns>The value of the parameter.</returns> public T GetParameter <T>(DotProtectContext context, IDnlibDef target, string name, T defValue = default(T)) { Dictionary <string, string> parameters; if (comp == null) { return(defValue); } if (comp is Packer && target == null) { // Packer parameters are stored in modules target = context.Modules[0]; } var objParams = context.Annotations.Get <ProtectionSettings>(target, ParametersKey); if (objParams == null) { return(defValue); } if (!objParams.TryGetValue(comp, out parameters)) { return(defValue); } string ret; if (parameters.TryGetValue(name, out ret)) { Type paramType = typeof(T); Type nullable = Nullable.GetUnderlyingType(paramType); if (nullable != null) { paramType = nullable; } if (paramType.IsEnum) { return((T)Enum.Parse(paramType, ret, true)); } return((T)Convert.ChangeType(ret, paramType)); } return(defValue); }
static void Debug(DotProtectContext context) { context.Logger.Info("Finalizing..."); for (int i = 0; i < context.OutputModules.Count; i++) { if (context.OutputSymbols[i] == null) { continue; } string path = Path.GetFullPath(Path.Combine(context.OutputDirectory, context.OutputPaths[i])); string dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } File.WriteAllBytes(Path.ChangeExtension(path, "pdb"), context.OutputSymbols[i]); } }
/// <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> /// Prints the copyright stuff and environment information. /// </summary> /// <param name="context">The working context.</param> static void PrintInfo(DotProtectContext context) { if (context.PackerInitiated) { context.Logger.Info("Protecting packer stub..."); } else { context.Logger.InfoFormat("{0} {1}", Version, Copyright); Type mono = Type.GetType("Mono.Runtime"); context.Logger.InfoFormat("Running on {0}, {1}, {2} bits", Environment.OSVersion, mono == null ? ".NET Framework v" + Environment.Version : mono.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, null), IntPtr.Size * 8); } }
/// <summary> /// Retrieves the available protection plugins. /// </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> protected virtual void GetPluginsInternal( DotProtectContext context, IList <Protection> protections, IList <Packer> packers, IList <DotProtectComponent> components) { try { Assembly protAsm = Assembly.Load("DotProtect.Protections"); AddPlugins(context, protections, packers, components, protAsm); } catch (Exception ex) { context.Logger.WarnException("Failed to load built-in protections.", ex); } try { Assembly renameAsm = Assembly.Load("DotProtect.Renamer"); AddPlugins(context, protections, packers, components, renameAsm); } catch (Exception ex) { context.Logger.WarnException("Failed to load renamer.", ex); } try { Assembly renameAsm = Assembly.Load("DotProtect.DynCipher"); AddPlugins(context, protections, packers, components, renameAsm); } catch (Exception ex) { context.Logger.WarnException("Failed to load dynamic cipher library.", ex); } foreach (string pluginPath in context.Project.PluginPaths) { string realPath = Path.Combine(context.BaseDirectory, pluginPath); try { Assembly plugin = Assembly.LoadFile(realPath); AddPlugins(context, protections, packers, components, plugin); } catch (Exception ex) { context.Logger.WarnException("Failed to load plugin '" + pluginPath + "'.", ex); } } }
/// <summary> /// Prints the environment information when error occurred. /// </summary> /// <param name="context">The working context.</param> static void PrintEnvironmentInfo(DotProtectContext context) { if (context.PackerInitiated) { return; } context.Logger.Error("---BEGIN DEBUG INFO---"); context.Logger.Error("Installed Framework Versions:"); foreach (string ver in GetFrameworkVersions()) { context.Logger.ErrorFormat(" {0}", ver.Trim()); } context.Logger.Error(""); if (context.Resolver != null) { context.Logger.Error("Cached assemblies:"); foreach (AssemblyDef asm in context.Resolver.GetCachedAssemblies()) { if (string.IsNullOrEmpty(asm.ManifestModule.Location)) { context.Logger.ErrorFormat(" {0}", asm.FullName); } else { context.Logger.ErrorFormat(" {0} ({1})", asm.FullName, asm.ManifestModule.Location); } foreach (var reference in asm.Modules.OfType <ModuleDefMD>().SelectMany(m => m.GetAssemblyRefs())) { context.Logger.ErrorFormat(" {0}", reference.FullName); } } } context.Logger.Error("---END DEBUG INFO---"); }
static void ProcessModule(DotProtectContext context) { }
/// <summary> /// Protects the stub using original project settings replace the current output with the protected stub. /// </summary> /// <param name="context">The working context.</param> /// <param name="fileName">The result file name.</param> /// <param name="module">The stub module.</param> /// <param name="snKey">The strong name key.</param> /// <param name="prot">The packer protection that applies to the stub.</param> protected void ProtectStub(DotProtectContext context, string fileName, byte[] module, StrongNameKey snKey, Protection prot = null) { string tmpDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); string outDir = Path.Combine(tmpDir, Path.GetRandomFileName()); Directory.CreateDirectory(tmpDir); for (int i = 0; i < context.OutputModules.Count; i++) { string path = Path.GetFullPath(Path.Combine(tmpDir, context.OutputPaths[i])); var dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } File.WriteAllBytes(path, context.OutputModules[i]); } File.WriteAllBytes(Path.Combine(tmpDir, fileName), module); var proj = new DotProtectProject(); proj.Seed = context.Project.Seed; foreach (Rule rule in context.Project.Rules) { proj.Rules.Add(rule); } proj.Add(new ProjectModule { Path = fileName }); proj.BaseDirectory = tmpDir; proj.OutputDirectory = outDir; foreach (var path in context.Project.ProbePaths) { proj.ProbePaths.Add(path); } proj.ProbePaths.Add(context.Project.BaseDirectory); PluginDiscovery discovery = null; if (prot != null) { var rule = new Rule { Preset = ProtectionPreset.None, Inherit = true, Pattern = "true" }; rule.Add(new SettingItem <Protection> { Id = prot.Id, Action = SettingItemAction.Add }); proj.Rules.Add(rule); discovery = new PackerDiscovery(prot); } try { DotProtectEngine.Run(new DotProtectParameters { Logger = new PackerLogger(context.Logger), PluginDiscovery = discovery, Marker = new PackerMarker(snKey), Project = proj, PackerInitiated = true }, context.token).Wait(); } catch (AggregateException ex) { context.Logger.Error("Failed to protect packer stub."); throw new DotProtectception(ex); } context.OutputModules = new[] { File.ReadAllBytes(Path.Combine(outDir, fileName)) }; context.OutputPaths = new[] { fileName }; }
protected override void GetPluginsInternal(DotProtectContext context, IList <Protection> protections, IList <Packer> packers, IList <DotProtectComponent> components) { base.GetPluginsInternal(context, protections, packers, components); protections.Add(prot); }
/// <summary> /// Executes the packer. /// </summary> /// <param name="context">The working context.</param> /// <param name="parameters">The parameters of packer.</param> protected internal abstract void Pack(DotProtectContext context, ProtectionParameters parameters);
/// <summary> /// Gets the protection parameters of the specified target. /// </summary> /// <param name="context">The context.</param> /// <param name="target">The protection target.</param> /// <returns>The parameters.</returns> public static ProtectionSettings GetParameters( DotProtectContext context, IDnlibDef target) { return(context.Annotations.Get <ProtectionSettings>(target, ParametersKey)); }
/// <summary> /// Sets the protection parameters of the specified target. /// </summary> /// <param name="context">The context.</param> /// <param name="target">The protection target.</param> /// <param name="parameters">The parameters.</param> public static void SetParameters( DotProtectContext context, IDnlibDef target, ProtectionSettings parameters) { context.Annotations.Set(target, ParametersKey, parameters); }
/// <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); } }