From 5535e24193082da3e05a99f0f7bbb5a8489c6322 Mon Sep 17 00:00:00 2001
From: Michael Wagner <43564011+horschmwagner@users.noreply.github.com>
Date: Thu, 2 Mar 2023 15:47:31 +0100
Subject: [PATCH] Update ConfuserEngine.cs
Confuser does write debug files (.pdb) even if debug=false in project file.
---
Confuser.Core/ConfuserEngine.cs | 1074 ++++++++++++++++---------------
1 file changed, 538 insertions(+), 536 deletions(-)
diff --git a/Confuser.Core/ConfuserEngine.cs b/Confuser.Core/ConfuserEngine.cs
index 519f8585..26df8a4c 100644
--- a/Confuser.Core/ConfuserEngine.cs
+++ b/Confuser.Core/ConfuserEngine.cs
@@ -1,551 +1,553 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Threading;
-using System.Threading.Tasks;
-using Confuser.Core.Project;
-using Confuser.Core.Services;
-using dnlib.DotNet;
-using dnlib.DotNet.Emit;
-using dnlib.DotNet.Writer;
-using Microsoft.Win32;
-using InformationalAttribute = System.Reflection.AssemblyInformationalVersionAttribute;
-using ProductAttribute = System.Reflection.AssemblyProductAttribute;
-using CopyrightAttribute = System.Reflection.AssemblyCopyrightAttribute;
-using MethodAttributes = dnlib.DotNet.MethodAttributes;
-using MethodImplAttributes = dnlib.DotNet.MethodImplAttributes;
-using TypeAttributes = dnlib.DotNet.TypeAttributes;
-
-namespace Confuser.Core {
- ///
- /// The processing engine of ConfuserEx.
- ///
- public static class ConfuserEngine {
- ///
- /// The version of ConfuserEx.
- ///
- public static readonly string Version;
-
- static readonly string Copyright;
-
- static ConfuserEngine() {
- Assembly assembly = typeof(ConfuserEngine).Assembly;
- var nameAttr = (ProductAttribute)assembly.GetCustomAttributes(typeof(ProductAttribute), false)[0];
- var verAttr = (InformationalAttribute)assembly.GetCustomAttributes(typeof(InformationalAttribute), false)[0];
- var cpAttr = (CopyrightAttribute)assembly.GetCustomAttributes(typeof(CopyrightAttribute), false)[0];
- Version = string.Format("{0} {1}", nameAttr.Product, verAttr.InformationalVersion);
- Copyright = cpAttr.Copyright;
-
- AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => {
- try {
- var asmName = new AssemblyName(e.Name);
- foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
- if (asm.GetName().Name == asmName.Name)
- return asm;
- return null;
- }
- catch {
- return null;
- }
- };
- }
-
- ///
- /// Runs the engine with the specified parameters.
- ///
- /// The parameters.
- /// The token used for cancellation.
- /// Task to run the engine.
- ///
- /// .Project is null.
- ///
- public static Task Run(ConfuserParameters parameters, CancellationToken? token = null) {
- if (parameters.Project == null)
- throw new ArgumentNullException("parameters");
- if (token == null)
- token = new CancellationTokenSource().Token;
- return Task.Factory.StartNew(() => RunInternal(parameters, token.Value), token.Value);
- }
-
- ///
- /// Runs the engine.
- ///
- /// The parameters.
- /// The cancellation token.
- static void RunInternal(ConfuserParameters parameters, CancellationToken token) {
- // 1. Setup context
- var context = new ConfuserContext();
- context.Logger = parameters.GetLogger();
- context.Project = parameters.Project.Clone();
- context.PackerInitiated = parameters.PackerInitiated;
- context.token = token;
-
- PrintInfo(context);
-
- bool ok = false;
- try {
- // Enable watermarking by default
- context.Project.Rules.Insert(0, new Rule {
- new SettingItem(WatermarkingProtection._Id)
- });
-
- var asmResolver = new ConfuserAssemblyResolver {EnableTypeDefCache = true};
- asmResolver.DefaultModuleContext = new ModuleContext(asmResolver);
- context.InternalResolver = asmResolver;
- context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, context.Project.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
- context.OutputDirectory = Path.Combine(context.Project.BaseDirectory, context.Project.OutputDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
- foreach (string probePath in context.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 prots;
- IList packers;
- IList components;
- parameters.GetPluginDiscovery().GetPlugins(context, 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 ConfuserException(ex);
- }
-
- components.Insert(0, new CoreComponent(context, 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(context.Project, context);
- context.Modules = new ModuleSorter(markings.Modules).Sort().ToList().AsReadOnly();
- foreach (var module in context.Modules)
- module.EnableTypeDefFindCache = false;
- context.OutputModules = Enumerable.Repeat(null, context.Modules.Count).ToArray();
- context.OutputSymbols = Enumerable.Repeat(null, context.Modules.Count).ToArray();
- context.OutputPaths = Enumerable.Repeat(null, context.Modules.Count).ToArray();
- context.Packer = markings.Packer;
- context.ExternalModules = markings.ExternalModules;
-
- context.CheckCancellation();
-
- // 5. Initialize components
- context.Logger.Info("Initializing...");
- foreach (ConfuserComponent comp in components) {
- try {
- comp.Initialize(context);
- }
- catch (Exception ex) {
- context.Logger.ErrorException("Error occured during initialization of '" + comp.Name + "'.", ex);
- throw new ConfuserException(ex);
- }
- context.CheckCancellation();
- }
-
- context.CheckCancellation();
-
- // 6. Build pipeline
- context.Logger.Debug("Building pipeline...");
- var pipeline = new ProtectionPipeline();
- context.Pipeline = pipeline;
- foreach (ConfuserComponent 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 (ConfuserException) {
- // 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.InternalResolver.Clear();
- context.Logger.Finish(ok);
- }
- }
-
- ///
- /// Runs the protection pipeline.
- ///
- /// The protection pipeline.
- /// The context.
- static void RunPipeline(ProtectionPipeline pipeline, ConfuserContext context) {
- Func> getAllDefs = () => context.Modules.SelectMany(module => module.FindDefinitions()).ToList();
- Func> getModuleDefs = module => module.FindDefinitions().ToList();
-
- context.CurrentModuleIndex = -1;
-
- pipeline.ExecuteStage(PipelineStage.Inspection, Inspection, () => getAllDefs(), context);
-
- var options = new ModuleWriterOptionsBase[context.Modules.Count];
- for (int i = 0; i < context.Modules.Count; i++) {
- context.CurrentModuleIndex = i;
- context.CurrentModuleWriterOptions = 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;
- }
-
- for (int i = 0; i < context.Modules.Count; i++) {
- context.CurrentModuleIndex = i;
- context.CurrentModuleWriterOptions = options[i];
-
- pipeline.ExecuteStage(PipelineStage.WriteModule, WriteModule, () => getModuleDefs(context.CurrentModule), context);
-
- context.OutputModules[i] = context.CurrentModuleOutput;
- context.OutputSymbols[i] = context.CurrentModuleSymbol;
- context.CurrentModuleWriterOptions = 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 Inspection(ConfuserContext context) {
- context.Logger.Info("Resolving dependencies...");
- foreach (var dependency in context.Modules
- .SelectMany(module => module.GetAssemblyRefs().Select(asmRef => Tuple.Create(asmRef, module)))) {
- try {
- context.Resolver.ResolveThrow(dependency.Item1, dependency.Item2);
- }
- catch (AssemblyResolveException ex) {
- context.Logger.ErrorException("Failed to resolve dependency of '" + dependency.Item2.Name + "'.", ex);
- throw new ConfuserException(ex);
- }
- }
-
- context.Logger.Debug("Checking Strong Name...");
- foreach (var module in context.Modules) {
- CheckStrongName(context, module);
- }
-
- var marker = context.Registry.GetService();
-
- context.Logger.Debug("Creating global .cctors...");
- foreach (ModuleDefMD module in context.Modules) {
- TypeDef modType = module.GlobalType;
- if (modType == null) {
- modType = new TypeDefUser("", "", null);
- modType.Attributes = TypeAttributes.AnsiClass;
- module.Types.Add(modType);
- marker.Mark(modType, null);
- }
- MethodDef cctor = modType.FindOrCreateStaticConstructor();
- if (!marker.IsMarked(cctor))
- marker.Mark(cctor, null);
- }
- }
-
- static void CheckStrongName(ConfuserContext context, ModuleDef module) {
- var snKey = context.Annotations.Get(module, Marker.SNKey);
- var snPubKeyBytes = context.Annotations.Get(module, Marker.SNPubKey)?.CreatePublicKey();
- var snDelaySign = context.Annotations.Get(module, Marker.SNDelaySig);
-
- if (snPubKeyBytes == null && snKey != null)
- snPubKeyBytes = snKey.PublicKey;
-
- bool moduleIsSignedOrDelayedSigned = module.IsStrongNameSigned || !module.Assembly.PublicKey.IsNullOrEmpty;
-
- bool isKeyProvided = snKey != null || (snDelaySign && snPubKeyBytes != null);
-
- if (!isKeyProvided && moduleIsSignedOrDelayedSigned)
- context.Logger.WarnFormat("[{0}] SN Key or SN public Key is not provided for a signed module, the output may not be working.", module.Name);
- else if (isKeyProvided && !moduleIsSignedOrDelayedSigned)
- context.Logger.WarnFormat("[{0}] SN Key or SN public Key is provided for an unsigned module, the output may not be working.", module.Name);
- else if (snPubKeyBytes != null && moduleIsSignedOrDelayedSigned &&
- !module.Assembly.PublicKey.Data.SequenceEqual(snPubKeyBytes))
- context.Logger.WarnFormat("[{0}] Provided SN public Key and signed module's public key do not match, the output may not be working.",
- module.Name);
- }
-
- static void CopyPEHeaders(PEHeadersOptions writerOptions, ModuleDefMD module) {
- var image = module.Metadata.PEImage;
- writerOptions.MajorImageVersion = image.ImageNTHeaders.OptionalHeader.MajorImageVersion;
- writerOptions.MajorLinkerVersion = image.ImageNTHeaders.OptionalHeader.MajorLinkerVersion;
- writerOptions.MajorOperatingSystemVersion = image.ImageNTHeaders.OptionalHeader.MajorOperatingSystemVersion;
- writerOptions.MajorSubsystemVersion = image.ImageNTHeaders.OptionalHeader.MajorSubsystemVersion;
- writerOptions.MinorImageVersion = image.ImageNTHeaders.OptionalHeader.MinorImageVersion;
- writerOptions.MinorLinkerVersion = image.ImageNTHeaders.OptionalHeader.MinorLinkerVersion;
- writerOptions.MinorOperatingSystemVersion = image.ImageNTHeaders.OptionalHeader.MinorOperatingSystemVersion;
- writerOptions.MinorSubsystemVersion = image.ImageNTHeaders.OptionalHeader.MinorSubsystemVersion;
- }
-
- static void BeginModule(ConfuserContext context) {
- context.Logger.InfoFormat("Processing module '{0}'...", context.CurrentModule.Name);
-
- context.CurrentModuleWriterOptions = new ModuleWriterOptions(context.CurrentModule);
- CopyPEHeaders(context.CurrentModuleWriterOptions.PEHeadersOptions, context.CurrentModule);
-
- if (!context.CurrentModule.IsILOnly || context.CurrentModule.VTableFixups != null)
- context.RequestNative(true);
-
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using Confuser.Core.Project;
+using Confuser.Core.Services;
+using dnlib.DotNet;
+using dnlib.DotNet.Emit;
+using dnlib.DotNet.Writer;
+using Microsoft.Win32;
+using InformationalAttribute = System.Reflection.AssemblyInformationalVersionAttribute;
+using ProductAttribute = System.Reflection.AssemblyProductAttribute;
+using CopyrightAttribute = System.Reflection.AssemblyCopyrightAttribute;
+using MethodAttributes = dnlib.DotNet.MethodAttributes;
+using MethodImplAttributes = dnlib.DotNet.MethodImplAttributes;
+using TypeAttributes = dnlib.DotNet.TypeAttributes;
+
+namespace Confuser.Core {
+ ///
+ /// The processing engine of ConfuserEx.
+ ///
+ public static class ConfuserEngine {
+ ///
+ /// The version of ConfuserEx.
+ ///
+ public static readonly string Version;
+
+ static readonly string Copyright;
+
+ static ConfuserEngine() {
+ Assembly assembly = typeof(ConfuserEngine).Assembly;
+ var nameAttr = (ProductAttribute)assembly.GetCustomAttributes(typeof(ProductAttribute), false)[0];
+ var verAttr = (InformationalAttribute)assembly.GetCustomAttributes(typeof(InformationalAttribute), false)[0];
+ var cpAttr = (CopyrightAttribute)assembly.GetCustomAttributes(typeof(CopyrightAttribute), false)[0];
+ Version = string.Format("{0} {1}", nameAttr.Product, verAttr.InformationalVersion);
+ Copyright = cpAttr.Copyright;
+
+ AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => {
+ try {
+ var asmName = new AssemblyName(e.Name);
+ foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
+ if (asm.GetName().Name == asmName.Name)
+ return asm;
+ return null;
+ }
+ catch {
+ return null;
+ }
+ };
+ }
+
+ ///
+ /// Runs the engine with the specified parameters.
+ ///
+ /// The parameters.
+ /// The token used for cancellation.
+ /// Task to run the engine.
+ ///
+ /// .Project is null.
+ ///
+ public static Task Run(ConfuserParameters parameters, CancellationToken? token = null) {
+ if (parameters.Project == null)
+ throw new ArgumentNullException("parameters");
+ if (token == null)
+ token = new CancellationTokenSource().Token;
+ return Task.Factory.StartNew(() => RunInternal(parameters, token.Value), token.Value);
+ }
+
+ ///
+ /// Runs the engine.
+ ///
+ /// The parameters.
+ /// The cancellation token.
+ static void RunInternal(ConfuserParameters parameters, CancellationToken token) {
+ // 1. Setup context
+ var context = new ConfuserContext();
+ context.Logger = parameters.GetLogger();
+ context.Project = parameters.Project.Clone();
+ context.PackerInitiated = parameters.PackerInitiated;
+ context.token = token;
+
+ PrintInfo(context);
+
+ bool ok = false;
+ try {
+ // Enable watermarking by default
+ context.Project.Rules.Insert(0, new Rule {
+ new SettingItem(WatermarkingProtection._Id)
+ });
+
+ var asmResolver = new ConfuserAssemblyResolver {EnableTypeDefCache = true};
+ asmResolver.DefaultModuleContext = new ModuleContext(asmResolver);
+ context.InternalResolver = asmResolver;
+ context.BaseDirectory = Path.Combine(Environment.CurrentDirectory, context.Project.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
+ context.OutputDirectory = Path.Combine(context.Project.BaseDirectory, context.Project.OutputDirectory.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar);
+ foreach (string probePath in context.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 prots;
+ IList packers;
+ IList components;
+ parameters.GetPluginDiscovery().GetPlugins(context, 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 ConfuserException(ex);
+ }
+
+ components.Insert(0, new CoreComponent(context, 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(context.Project, context);
+ context.Modules = new ModuleSorter(markings.Modules).Sort().ToList().AsReadOnly();
+ foreach (var module in context.Modules)
+ module.EnableTypeDefFindCache = false;
+ context.OutputModules = Enumerable.Repeat(null, context.Modules.Count).ToArray();
+ context.OutputSymbols = Enumerable.Repeat(null, context.Modules.Count).ToArray();
+ context.OutputPaths = Enumerable.Repeat(null, context.Modules.Count).ToArray();
+ context.Packer = markings.Packer;
+ context.ExternalModules = markings.ExternalModules;
+
+ context.CheckCancellation();
+
+ // 5. Initialize components
+ context.Logger.Info("Initializing...");
+ foreach (ConfuserComponent comp in components) {
+ try {
+ comp.Initialize(context);
+ }
+ catch (Exception ex) {
+ context.Logger.ErrorException("Error occured during initialization of '" + comp.Name + "'.", ex);
+ throw new ConfuserException(ex);
+ }
+ context.CheckCancellation();
+ }
+
+ context.CheckCancellation();
+
+ // 6. Build pipeline
+ context.Logger.Debug("Building pipeline...");
+ var pipeline = new ProtectionPipeline();
+ context.Pipeline = pipeline;
+ foreach (ConfuserComponent 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 (ConfuserException) {
+ // 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.InternalResolver.Clear();
+ context.Logger.Finish(ok);
+ }
+ }
+
+ ///
+ /// Runs the protection pipeline.
+ ///
+ /// The protection pipeline.
+ /// The context.
+ static void RunPipeline(ProtectionPipeline pipeline, ConfuserContext context) {
+ Func> getAllDefs = () => context.Modules.SelectMany(module => module.FindDefinitions()).ToList();
+ Func> getModuleDefs = module => module.FindDefinitions().ToList();
+
+ context.CurrentModuleIndex = -1;
+
+ pipeline.ExecuteStage(PipelineStage.Inspection, Inspection, () => getAllDefs(), context);
+
+ var options = new ModuleWriterOptionsBase[context.Modules.Count];
+ for (int i = 0; i < context.Modules.Count; i++) {
+ context.CurrentModuleIndex = i;
+ context.CurrentModuleWriterOptions = 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;
+ }
+
+ for (int i = 0; i < context.Modules.Count; i++) {
+ context.CurrentModuleIndex = i;
+ context.CurrentModuleWriterOptions = options[i];
+
+ pipeline.ExecuteStage(PipelineStage.WriteModule, WriteModule, () => getModuleDefs(context.CurrentModule), context);
+
+ context.OutputModules[i] = context.CurrentModuleOutput;
+ context.OutputSymbols[i] = context.CurrentModuleSymbol;
+ context.CurrentModuleWriterOptions = 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 Inspection(ConfuserContext context) {
+ context.Logger.Info("Resolving dependencies...");
+ foreach (var dependency in context.Modules
+ .SelectMany(module => module.GetAssemblyRefs().Select(asmRef => Tuple.Create(asmRef, module)))) {
+ try {
+ context.Resolver.ResolveThrow(dependency.Item1, dependency.Item2);
+ }
+ catch (AssemblyResolveException ex) {
+ context.Logger.ErrorException("Failed to resolve dependency of '" + dependency.Item2.Name + "'.", ex);
+ throw new ConfuserException(ex);
+ }
+ }
+
+ context.Logger.Debug("Checking Strong Name...");
+ foreach (var module in context.Modules) {
+ CheckStrongName(context, module);
+ }
+
+ var marker = context.Registry.GetService();
+
+ context.Logger.Debug("Creating global .cctors...");
+ foreach (ModuleDefMD module in context.Modules) {
+ TypeDef modType = module.GlobalType;
+ if (modType == null) {
+ modType = new TypeDefUser("", "", null);
+ modType.Attributes = TypeAttributes.AnsiClass;
+ module.Types.Add(modType);
+ marker.Mark(modType, null);
+ }
+ MethodDef cctor = modType.FindOrCreateStaticConstructor();
+ if (!marker.IsMarked(cctor))
+ marker.Mark(cctor, null);
+ }
+ }
+
+ static void CheckStrongName(ConfuserContext context, ModuleDef module) {
+ var snKey = context.Annotations.Get(module, Marker.SNKey);
+ var snPubKeyBytes = context.Annotations.Get(module, Marker.SNPubKey)?.CreatePublicKey();
+ var snDelaySign = context.Annotations.Get(module, Marker.SNDelaySig);
+
+ if (snPubKeyBytes == null && snKey != null)
+ snPubKeyBytes = snKey.PublicKey;
+
+ bool moduleIsSignedOrDelayedSigned = module.IsStrongNameSigned || !module.Assembly.PublicKey.IsNullOrEmpty;
+
+ bool isKeyProvided = snKey != null || (snDelaySign && snPubKeyBytes != null);
+
+ if (!isKeyProvided && moduleIsSignedOrDelayedSigned)
+ context.Logger.WarnFormat("[{0}] SN Key or SN public Key is not provided for a signed module, the output may not be working.", module.Name);
+ else if (isKeyProvided && !moduleIsSignedOrDelayedSigned)
+ context.Logger.WarnFormat("[{0}] SN Key or SN public Key is provided for an unsigned module, the output may not be working.", module.Name);
+ else if (snPubKeyBytes != null && moduleIsSignedOrDelayedSigned &&
+ !module.Assembly.PublicKey.Data.SequenceEqual(snPubKeyBytes))
+ context.Logger.WarnFormat("[{0}] Provided SN public Key and signed module's public key do not match, the output may not be working.",
+ module.Name);
+ }
+
+ static void CopyPEHeaders(PEHeadersOptions writerOptions, ModuleDefMD module) {
+ var image = module.Metadata.PEImage;
+ writerOptions.MajorImageVersion = image.ImageNTHeaders.OptionalHeader.MajorImageVersion;
+ writerOptions.MajorLinkerVersion = image.ImageNTHeaders.OptionalHeader.MajorLinkerVersion;
+ writerOptions.MajorOperatingSystemVersion = image.ImageNTHeaders.OptionalHeader.MajorOperatingSystemVersion;
+ writerOptions.MajorSubsystemVersion = image.ImageNTHeaders.OptionalHeader.MajorSubsystemVersion;
+ writerOptions.MinorImageVersion = image.ImageNTHeaders.OptionalHeader.MinorImageVersion;
+ writerOptions.MinorLinkerVersion = image.ImageNTHeaders.OptionalHeader.MinorLinkerVersion;
+ writerOptions.MinorOperatingSystemVersion = image.ImageNTHeaders.OptionalHeader.MinorOperatingSystemVersion;
+ writerOptions.MinorSubsystemVersion = image.ImageNTHeaders.OptionalHeader.MinorSubsystemVersion;
+ }
+
+ static void BeginModule(ConfuserContext context) {
+ context.Logger.InfoFormat("Processing module '{0}'...", context.CurrentModule.Name);
+
+ context.CurrentModuleWriterOptions = new ModuleWriterOptions(context.CurrentModule);
+ CopyPEHeaders(context.CurrentModuleWriterOptions.PEHeadersOptions, context.CurrentModule);
+
+ if (!context.CurrentModule.IsILOnly || context.CurrentModule.VTableFixups != null)
+ context.RequestNative(true);
+
var snKey = context.Annotations.Get(context.CurrentModule, Marker.SNKey);
var snPubKey = context.Annotations.Get(context.CurrentModule, Marker.SNPubKey);
var snSigKey = context.Annotations.Get(context.CurrentModule, Marker.SNSigKey);
- var snSigPubKey = context.Annotations.Get(context.CurrentModule, Marker.SNSigPubKey);
-
+ var snSigPubKey = context.Annotations.Get(context.CurrentModule, Marker.SNSigPubKey);
+
var snDelaySig = context.Annotations.Get(context.CurrentModule, Marker.SNDelaySig, false);
- context.CurrentModuleWriterOptions.DelaySign = snDelaySig;
-
- if (snKey != null && snPubKey != null && snSigKey != null && snSigPubKey != null)
- context.CurrentModuleWriterOptions.InitializeEnhancedStrongNameSigning(context.CurrentModule, snSigKey, snSigPubKey, snKey, snPubKey);
+ context.CurrentModuleWriterOptions.DelaySign = snDelaySig;
+
+ if (snKey != null && snPubKey != null && snSigKey != null && snSigPubKey != null)
+ context.CurrentModuleWriterOptions.InitializeEnhancedStrongNameSigning(context.CurrentModule, snSigKey, snSigPubKey, snKey, snPubKey);
else if (snSigPubKey != null && snSigKey != null)
context.CurrentModuleWriterOptions.InitializeEnhancedStrongNameSigning(context.CurrentModule, snSigKey, snSigPubKey);
else
- context.CurrentModuleWriterOptions.InitializeStrongNameSigning(context.CurrentModule, snKey);
-
+ context.CurrentModuleWriterOptions.InitializeStrongNameSigning(context.CurrentModule, snKey);
+
if (snDelaySig) {
- context.CurrentModuleWriterOptions.StrongNamePublicKey = snPubKey;
- context.CurrentModuleWriterOptions.StrongNameKey = null;
- }
-
- 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);
- }
- }
- }
-
- static void ProcessModule(ConfuserContext context) =>
- context.CurrentModuleWriterOptions.WriterEvent += (sender, e) => context.CheckCancellation();
-
- static void OptimizeMethods(ConfuserContext context) {
- foreach (TypeDef type in context.CurrentModule.GetTypes())
- foreach (MethodDef method in type.Methods) {
- if (method.Body != null)
- method.Body.Instructions.OptimizeMacros();
- }
- }
-
- static void EndModule(ConfuserContext context) {
- string output = context.Modules[context.CurrentModuleIndex].Location;
- if (!(output is null)) {
- if (!Path.IsPathRooted(output))
- output = Path.Combine(context.BaseDirectory, output);
- string relativeOutput = Utils.GetRelativePath(output, context.BaseDirectory);
+ context.CurrentModuleWriterOptions.StrongNamePublicKey = snPubKey;
+ context.CurrentModuleWriterOptions.StrongNameKey = null;
+ }
+
+ 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);
+ }
+ }
+ }
+
+ static void ProcessModule(ConfuserContext context) =>
+ context.CurrentModuleWriterOptions.WriterEvent += (sender, e) => context.CheckCancellation();
+
+ static void OptimizeMethods(ConfuserContext context) {
+ foreach (TypeDef type in context.CurrentModule.GetTypes())
+ foreach (MethodDef method in type.Methods) {
+ if (method.Body != null)
+ method.Body.Instructions.OptimizeMacros();
+ }
+ }
+
+ static void EndModule(ConfuserContext context) {
+ string output = context.Modules[context.CurrentModuleIndex].Location;
+ if (!(output is null)) {
+ if (!Path.IsPathRooted(output))
+ output = Path.Combine(context.BaseDirectory, output);
+ string relativeOutput = Utils.GetRelativePath(output, context.BaseDirectory);
if (relativeOutput is null) {
context.Logger.WarnFormat("Input file is not inside the base directory. Relative path can't be created. Placing file into output root." +
Environment.NewLine + "Responsible file is: {0}", output);
output = Path.GetFileName(output);
} else {
output = relativeOutput;
- }
- }
- else {
- output = context.CurrentModule.Name;
- }
- context.OutputPaths[context.CurrentModuleIndex] = output;
- }
-
- static void WriteModule(ConfuserContext 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();
- }
-
- static void Debug(ConfuserContext 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]);
- }
- }
-
- static void Pack(ConfuserContext context) {
- if (context.Packer != null) {
- context.Logger.Info("Packing...");
- context.Packer.Pack(context, new ProtectionParameters(context.Packer, context.Modules.OfType().ToList()));
- }
- }
-
- static void SaveModules(ConfuserContext context) {
- context.InternalResolver.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]);
- }
- }
-
- ///
- /// Prints the copyright stuff and environment information.
- ///
- /// The working context.
- static void PrintInfo(ConfuserContext 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);
- }
- }
-
- static IEnumerable GetFrameworkVersions() {
- // http://msdn.microsoft.com/en-us/library/hh925568.aspx
-
- using (RegistryKey ndpKey =
- RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
- OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\")) {
- foreach (string versionKeyName in ndpKey.GetSubKeyNames()) {
- if (!versionKeyName.StartsWith("v"))
- continue;
-
- RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
- var name = (string)versionKey.GetValue("Version", "");
- string sp = versionKey.GetValue("SP", "").ToString();
- string install = versionKey.GetValue("Install", "").ToString();
- if (install == "" || sp != "" && install == "1")
- yield return versionKeyName + " " + name;
-
- if (name != "")
- continue;
-
- foreach (string subKeyName in versionKey.GetSubKeyNames()) {
- RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
- name = (string)subKey.GetValue("Version", "");
- if (name != "")
- sp = subKey.GetValue("SP", "").ToString();
- install = subKey.GetValue("Install", "").ToString();
-
- if (install == "")
- yield return versionKeyName + " " + name;
- else if (install == "1")
- yield return " " + subKeyName + " " + name;
- }
- }
- }
-
- using (RegistryKey ndpKey =
- RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
- OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\")) {
- if (ndpKey.GetValue("Release") == null)
- yield break;
- var releaseKey = (int)ndpKey.GetValue("Release");
- yield return "v4.5 " + releaseKey;
- }
- }
-
- ///
- /// Prints the environment information when error occurred.
- ///
- /// The working context.
- static void PrintEnvironmentInfo(ConfuserContext 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.InternalResolver.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().SelectMany(m => m.GetAssemblyRefs()))
- context.Logger.ErrorFormat(" {0}", reference.FullName);
- }
- }
-
- context.Logger.Error("---END DEBUG INFO---");
- }
- }
-}
+ }
+ }
+ else {
+ output = context.CurrentModule.Name;
+ }
+ context.OutputPaths[context.CurrentModuleIndex] = output;
+ }
+
+ static void WriteModule(ConfuserContext 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();
+ }
+
+ static void Debug(ConfuserContext context) {
+ context.Logger.Info("Finalizing...");
+ if(!context.Project.Debug)
+ return;
+ 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]);
+ }
+ }
+
+ static void Pack(ConfuserContext context) {
+ if (context.Packer != null) {
+ context.Logger.Info("Packing...");
+ context.Packer.Pack(context, new ProtectionParameters(context.Packer, context.Modules.OfType().ToList()));
+ }
+ }
+
+ static void SaveModules(ConfuserContext context) {
+ context.InternalResolver.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]);
+ }
+ }
+
+ ///
+ /// Prints the copyright stuff and environment information.
+ ///
+ /// The working context.
+ static void PrintInfo(ConfuserContext 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);
+ }
+ }
+
+ static IEnumerable GetFrameworkVersions() {
+ // http://msdn.microsoft.com/en-us/library/hh925568.aspx
+
+ using (RegistryKey ndpKey =
+ RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
+ OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\")) {
+ foreach (string versionKeyName in ndpKey.GetSubKeyNames()) {
+ if (!versionKeyName.StartsWith("v"))
+ continue;
+
+ RegistryKey versionKey = ndpKey.OpenSubKey(versionKeyName);
+ var name = (string)versionKey.GetValue("Version", "");
+ string sp = versionKey.GetValue("SP", "").ToString();
+ string install = versionKey.GetValue("Install", "").ToString();
+ if (install == "" || sp != "" && install == "1")
+ yield return versionKeyName + " " + name;
+
+ if (name != "")
+ continue;
+
+ foreach (string subKeyName in versionKey.GetSubKeyNames()) {
+ RegistryKey subKey = versionKey.OpenSubKey(subKeyName);
+ name = (string)subKey.GetValue("Version", "");
+ if (name != "")
+ sp = subKey.GetValue("SP", "").ToString();
+ install = subKey.GetValue("Install", "").ToString();
+
+ if (install == "")
+ yield return versionKeyName + " " + name;
+ else if (install == "1")
+ yield return " " + subKeyName + " " + name;
+ }
+ }
+ }
+
+ using (RegistryKey ndpKey =
+ RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, "").
+ OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\")) {
+ if (ndpKey.GetValue("Release") == null)
+ yield break;
+ var releaseKey = (int)ndpKey.GetValue("Release");
+ yield return "v4.5 " + releaseKey;
+ }
+ }
+
+ ///
+ /// Prints the environment information when error occurred.
+ ///
+ /// The working context.
+ static void PrintEnvironmentInfo(ConfuserContext 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.InternalResolver.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().SelectMany(m => m.GetAssemblyRefs()))
+ context.Logger.ErrorFormat(" {0}", reference.FullName);
+ }
+ }
+
+ context.Logger.Error("---END DEBUG INFO---");
+ }
+ }
+}