diff --git a/Confuser.Core/ConfuserContext.cs b/Confuser.Core/ConfuserContext.cs index a7e3a9034..94092bec1 100644 --- a/Confuser.Core/ConfuserContext.cs +++ b/Confuser.Core/ConfuserContext.cs @@ -161,28 +161,36 @@ public void CheckCancellation() { /// Requests the current module to be written as mix-mode module, and return the native writer options. /// /// The native writer options. - public NativeModuleWriterOptions RequestNative() { + public NativeModuleWriterOptions RequestNative(bool optimizeImageSize) { if (CurrentModule == null) return null; if (CurrentModuleWriterOptions == null) - CurrentModuleWriterOptions = new NativeModuleWriterOptions(CurrentModule, true); - - if (CurrentModuleWriterOptions is NativeModuleWriterOptions) - return (NativeModuleWriterOptions)CurrentModuleWriterOptions; - var newOptions = new NativeModuleWriterOptions(CurrentModule, true); + CurrentModuleWriterOptions = new NativeModuleWriterOptions(CurrentModule, optimizeImageSize); + // Clone the current options to the new options - newOptions.AddCheckSum = CurrentModuleWriterOptions.AddCheckSum; - newOptions.Cor20HeaderOptions = CurrentModuleWriterOptions.Cor20HeaderOptions; - newOptions.Logger = CurrentModuleWriterOptions.Logger; - newOptions.MetadataLogger = CurrentModuleWriterOptions.MetadataLogger; - newOptions.MetadataOptions = CurrentModuleWriterOptions.MetadataOptions; - newOptions.ModuleKind = CurrentModuleWriterOptions.ModuleKind; - newOptions.PEHeadersOptions = CurrentModuleWriterOptions.PEHeadersOptions; - newOptions.ShareMethodBodies = CurrentModuleWriterOptions.ShareMethodBodies; - newOptions.DelaySign = CurrentModuleWriterOptions.DelaySign; - newOptions.StrongNameKey = CurrentModuleWriterOptions.StrongNameKey; - newOptions.StrongNamePublicKey = CurrentModuleWriterOptions.StrongNamePublicKey; - newOptions.Win32Resources = CurrentModuleWriterOptions.Win32Resources; + var newOptions = new NativeModuleWriterOptions(CurrentModule, optimizeImageSize) { + AddCheckSum = CurrentModuleWriterOptions.AddCheckSum, + AddMvidSection = CurrentModuleWriterOptions.AddMvidSection, + Cor20HeaderOptions = CurrentModuleWriterOptions.Cor20HeaderOptions, + GetPdbContentId = CurrentModuleWriterOptions.GetPdbContentId, + Logger = CurrentModuleWriterOptions.Logger, + MetadataLogger = CurrentModuleWriterOptions.MetadataLogger, + MetadataOptions = CurrentModuleWriterOptions.MetadataOptions, + ModuleKind = CurrentModuleWriterOptions.ModuleKind, + NoWin32Resources = CurrentModuleWriterOptions.NoWin32Resources, + PdbChecksumAlgorithm = CurrentModuleWriterOptions.PdbChecksumAlgorithm, + PdbFileName = CurrentModuleWriterOptions.PdbFileName, + PdbFileNameInDebugDirectory = CurrentModuleWriterOptions.PdbFileNameInDebugDirectory, + PdbOptions = CurrentModuleWriterOptions.PdbOptions, + PdbStream = CurrentModuleWriterOptions.PdbStream, + PEHeadersOptions = CurrentModuleWriterOptions.PEHeadersOptions, + ShareMethodBodies = CurrentModuleWriterOptions.ShareMethodBodies, + DelaySign = CurrentModuleWriterOptions.DelaySign, + StrongNameKey = CurrentModuleWriterOptions.StrongNameKey, + StrongNamePublicKey = CurrentModuleWriterOptions.StrongNamePublicKey, + Win32Resources = CurrentModuleWriterOptions.Win32Resources, + WritePdb = CurrentModuleWriterOptions.WritePdb, + }; CurrentModuleWriterOptions = newOptions; return newOptions; } diff --git a/Confuser.Core/ConfuserEngine.cs b/Confuser.Core/ConfuserEngine.cs index 07542b6ac..0f33c2886 100644 --- a/Confuser.Core/ConfuserEngine.cs +++ b/Confuser.Core/ConfuserEngine.cs @@ -332,11 +332,10 @@ static void BeginModule(ConfuserContext context) { context.Logger.InfoFormat("Processing module '{0}'...", context.CurrentModule.Name); context.CurrentModuleWriterOptions = new ModuleWriterOptions(context.CurrentModule); - context.CurrentModuleWriterOptions.WriterEvent += (sender, e) => context.CheckCancellation(); CopyPEHeaders(context.CurrentModuleWriterOptions.PEHeadersOptions, context.CurrentModule); if (!context.CurrentModule.IsILOnly || context.CurrentModule.VTableFixups != null) - context.RequestNative(); + context.RequestNative(true); var snKey = context.Annotations.Get(context.CurrentModule, Marker.SNKey); var snPubKey = context.Annotations.Get(context.CurrentModule, Marker.SNPubKey); @@ -367,7 +366,8 @@ static void BeginModule(ConfuserContext context) { } } - static void ProcessModule(ConfuserContext context) { } + static void ProcessModule(ConfuserContext context) => + context.CurrentModuleWriterOptions.WriterEvent += (sender, e) => context.CheckCancellation(); static void OptimizeMethods(ConfuserContext context) { foreach (TypeDef type in context.CurrentModule.GetTypes()) diff --git a/Confuser.Protections/AntiTamper/AntiTamperProtection.cs b/Confuser.Protections/AntiTamper/AntiTamperProtection.cs index efcf01b0d..a528f845c 100644 --- a/Confuser.Protections/AntiTamper/AntiTamperProtection.cs +++ b/Confuser.Protections/AntiTamper/AntiTamperProtection.cs @@ -3,6 +3,7 @@ using Confuser.Core; using Confuser.Protections.AntiTamper; using dnlib.DotNet; +using dnlib.DotNet.Writer; namespace Confuser.Protections { public interface IAntiTamperService { @@ -41,6 +42,7 @@ protected override void Initialize(ConfuserContext context) { } protected override void PopulatePipeline(ProtectionPipeline pipeline) { + pipeline.InsertPostStage(PipelineStage.BeginModule, new ModuleWriterSetupPhase(this)); pipeline.InsertPreStage(PipelineStage.OptimizeMethods, new InjectPhase(this)); pipeline.InsertPreStage(PipelineStage.EndModule, new MDPhase(this)); } @@ -49,6 +51,25 @@ public void ExcludeMethod(ConfuserContext context, MethodDef method) { ProtectionParameters.GetParameters(context, method).Remove(this); } + class ModuleWriterSetupPhase : ProtectionPhase { + public ModuleWriterSetupPhase(AntiTamperProtection parent) : base(parent) { } + + /// + public override ProtectionTargets Targets => ProtectionTargets.Methods; + + /// + public override string Name => "Anti-tamper module writer preparation"; + + /// + protected override void Execute(ConfuserContext context, ProtectionParameters parameters) { + if (!parameters.Targets.Any()) return; + + if (context.CurrentModuleWriterOptions is NativeModuleWriterOptions nativeOptions) { + context.RequestNative(false); + } + } + } + class InjectPhase : ProtectionPhase { public InjectPhase(AntiTamperProtection parent) : base(parent) { } diff --git a/Confuser.Protections/AntiTamper/NormalMode.cs b/Confuser.Protections/AntiTamper/NormalMode.cs index d984687bb..ec6313072 100644 --- a/Confuser.Protections/AntiTamper/NormalMode.cs +++ b/Confuser.Protections/AntiTamper/NormalMode.cs @@ -102,10 +102,6 @@ public void HandleMD(AntiTamperProtection parent, ConfuserContext context, Prote void WriterEvent(object sender, ModuleWriterEventArgs e) { switch (e.Event) { - case ModuleWriterEvent.Begin when e.Writer is NativeModuleWriter nativeWriter: - // disable the optimization of the image size for the native writer, so the method bodies can be protected. - nativeWriter.Options = new NativeModuleWriterOptions(nativeWriter.ModuleDefMD, false); - break; case ModuleWriterEvent.MDEndCreateTables: CreateSections(e.Writer); break; diff --git a/Tests/244_ClrProtection.Test/ProtectClrAssemblyTest.cs b/Tests/244_ClrProtection.Test/ProtectClrAssemblyTest.cs index d0973fd38..a75d91b82 100644 --- a/Tests/244_ClrProtection.Test/ProtectClrAssemblyTest.cs +++ b/Tests/244_ClrProtection.Test/ProtectClrAssemblyTest.cs @@ -39,5 +39,16 @@ public Task TypeScrambleProtection() => Run( Array.Empty(), new SettingItem("typescramble"), $"_{nameof(TypeScrambleProtection)}"); + + [Fact] + [Trait("Category", "Protection")] + [Trait("Protection", "anti tamper")] + [Trait("Protection", "resources")] + [Trait("Issue", "https://github.com/mkaring/ConfuserEx/issues/244")] + public Task AntiTamperResourceProtection() => Run( + "244_ClrProtection.exe", + Array.Empty(), + new[] {new SettingItem("anti tamper"), new SettingItem("resources") }, + $"_{nameof(AntiTamperResourceProtection)}"); } }