From 6b0a288431340e93b3f115eadf601f7e31b478d2 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Thu, 9 Feb 2023 20:16:27 +0200 Subject: [PATCH 01/13] Update ModuleDefinitionExtensions.cs --- .../Extensions/AsmResolver/ModuleDefinitionExtensions.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/BitMono.Utilities/Extensions/AsmResolver/ModuleDefinitionExtensions.cs b/src/BitMono.Utilities/Extensions/AsmResolver/ModuleDefinitionExtensions.cs index c8e2f37f..7288aa40 100644 --- a/src/BitMono.Utilities/Extensions/AsmResolver/ModuleDefinitionExtensions.cs +++ b/src/BitMono.Utilities/Extensions/AsmResolver/ModuleDefinitionExtensions.cs @@ -3,14 +3,11 @@ public static class ModuleDefinitionExtensions { [return: AllowNull] - public static TMember ResolveOrThrow(this ModuleDefinition source, Type type) + public static TMember ResolveOrThrow(this ModuleDefinition source, Type type) where TMember : class, IMetadataMember { - if (source.TryLookupMember(new MetadataToken((uint)type.MetadataToken), out var metadataMember)) + if (source.TryLookupMember(new MetadataToken((uint)type.MetadataToken), out TMember? member)) { - if (metadataMember is TMember member) - { - return member; - } + return member; } throw new ArgumentException($"Unable to resolve member {type.FullName}"); } From 3fee2b72b470a24e269b41d23500d39ce3f2d75a Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Thu, 9 Feb 2023 20:20:20 +0200 Subject: [PATCH 02/13] Update CallToCalli.cs --- src/BitMono.Protections/CallToCalli.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BitMono.Protections/CallToCalli.cs b/src/BitMono.Protections/CallToCalli.cs index a019f8b4..5d33926e 100644 --- a/src/BitMono.Protections/CallToCalli.cs +++ b/src/BitMono.Protections/CallToCalli.cs @@ -27,7 +27,7 @@ public Task ExecuteAsync(ProtectionContext context, ProtectionParameters paramet for (var i = 0; i < body.Instructions.Count; i++) { var instruction = body.Instructions[i]; - if (instruction.OpCode.FlowControl == CilFlowControl.Call && instruction.Operand is IMethodDescriptor methodDescriptor) + if (instruction.OpCode == CilOpCodes.Call && instruction.Operand is IMethodDescriptor methodDescriptor) { var callingMethod = methodDescriptor.Resolve(); if (callingMethod != null) From 72ede74e3ff1b8e209803b6540798e6212a17e66 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Fri, 10 Feb 2023 17:39:28 +0200 Subject: [PATCH 03/13] Update issue templates --- .github/ISSUE_TEMPLATE/BUG_REPORT.yml | 2 ++ .github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml | 34 +--------------------- 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml index 83142536..1149c7a8 100644 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml @@ -73,6 +73,7 @@ body: options: - CLI - GUI + - Other validations: required: false - type: dropdown @@ -85,5 +86,6 @@ body: - Windows - Linux - Mac + - Other validations: required: false \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml index 24ed832a..1ad5a7ab 100644 --- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml @@ -1,22 +1,6 @@ name: "💡 Feature Request" description: Create a new ticket for a new feature request. body: - - type: textarea - id: implementation_pr - attributes: - label: "Implementation PR" - description: Pull request used - placeholder: "#Pull Request ID" - validations: - required: false - - type: textarea - id: reference_issues - attributes: - label: "Reference Issues" - description: Common issues - placeholder: "#Issues IDs" - validations: - required: false - type: textarea id: summary attributes: @@ -32,20 +16,4 @@ body: description: Indicate here some basic examples of your feature. placeholder: A few specific words about your feature request. validations: - required: true - - type: textarea - id: drawbacks - attributes: - label: "Drawbacks" - description: What are the drawbacks/impacts of your feature request ? - placeholder: Identify the drawbacks and impacts while being neutral on your feature request - validations: - required: true - - type: textarea - id: unresolved_question - attributes: - label: "Unresolved questions" - description: What questions still remain unresolved ? - placeholder: Identify any unresolved issues. - validations: - required: false \ No newline at end of file + required: true \ No newline at end of file From 2598e177eeb92531eb05cf624a3da6360cbbb9c7 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Fri, 10 Feb 2023 17:39:34 +0200 Subject: [PATCH 04/13] Delete idea files --- .idea/.idea.BitMono/.idea/indexLayout.xml | 8 -------- .idea/.idea.BitMono/.idea/vcs.xml | 6 ------ 2 files changed, 14 deletions(-) delete mode 100644 .idea/.idea.BitMono/.idea/indexLayout.xml delete mode 100644 .idea/.idea.BitMono/.idea/vcs.xml diff --git a/.idea/.idea.BitMono/.idea/indexLayout.xml b/.idea/.idea.BitMono/.idea/indexLayout.xml deleted file mode 100644 index 7b08163c..00000000 --- a/.idea/.idea.BitMono/.idea/indexLayout.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/.idea.BitMono/.idea/vcs.xml b/.idea/.idea.BitMono/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/.idea.BitMono/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From fa2d5fdba5cea3153401ecf24547239fb9ede06a Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Fri, 10 Feb 2023 17:49:59 +0200 Subject: [PATCH 05/13] Add deepsource in README --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index baa32742..2425f04b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![Build status][image_appveyor_main_badge]][appveyor_main_build] [![Test status][image_test]][test] [![Codefactor][image_codefactor]][codefactor] +[![DeepSource][image_deepsource]][deepsource] [![Gitter Chat][image_gitter]][gitter] [![MIT License][image_license]][license] @@ -85,6 +86,7 @@ Credits [test]: https://ci.appveyor.com/project/sunnamed434/bitmono/branch/main/tests [codefactor]: https://www.codefactor.io/repository/github/sunnamed434/bitmono/overview/main +[deepsource]: https://deepsource.io/gh/sunnamed434/BitMono/?ref=repository-badge [gitter]: https://gitter.im/BitMonoSpeech/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge [license]: https://github.com/sunnamed434/BitMono/blob/main/LICENSE [asmresolver]: https://github.com/Washi1337/AsmResolver @@ -107,6 +109,7 @@ Credits [image_build]: https://ci.appveyor.com/api/projects/status/8jh35hfno6riq25j?svg=true&style=plastic [image_test]: https://img.shields.io/appveyor/tests/sunnamed434/bitmono/main [image_codefactor]: https://www.codefactor.io/repository/github/sunnamed434/bitmono/badge/main +[image_deepsource]: https://deepsource.io/gh/sunnamed434/BitMono.svg/?label=active+issues&show_trend=true&token=_FJf25YbtCpPyX7SRveXCaGd [image_gitter]: https://badges.gitter.im/BitMonoSpeech/community.svg?style=plastic [image_license]: https://img.shields.io/github/license/sunnamed434/bitmono [image_appveyor_main_badge]: https://ci.appveyor.com/api/projects/status/8jh35hfno6riq25j/branch/main?svg=true From 67370e2a22c3f0c7c6cf62e09c9d3859189546d4 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Fri, 10 Feb 2023 17:57:48 +0200 Subject: [PATCH 06/13] Fix unit tests --- BitMono.sln | 7 ++ .../BitMono.Core.Tests.csproj | 68 +++++++++---------- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/BitMono.sln b/BitMono.sln index 7d06b79b..5f7cbca4 100644 --- a/BitMono.sln +++ b/BitMono.sln @@ -58,6 +58,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitMono.Core.TestCases.Meth EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitMono.Core.TestCases.Types", "test\TestBinaries\DotNet\BitMono.Core.TestCases.Types\BitMono.Core.TestCases.Types.csproj", "{5DC793B1-F82B-4BC7-99C9-FE8C1545E1F7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitMono.Core.TestCases.Reflection", "test\TestBinaries\DotNet\BitMono.Core.TestCases.Reflection\BitMono.Core.TestCases.Reflection.csproj", "{1683308C-36D4-49B1-8CCE-9DDE09336856}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -138,6 +140,10 @@ Global {5DC793B1-F82B-4BC7-99C9-FE8C1545E1F7}.Debug|Any CPU.Build.0 = Debug|Any CPU {5DC793B1-F82B-4BC7-99C9-FE8C1545E1F7}.Release|Any CPU.ActiveCfg = Release|Any CPU {5DC793B1-F82B-4BC7-99C9-FE8C1545E1F7}.Release|Any CPU.Build.0 = Release|Any CPU + {1683308C-36D4-49B1-8CCE-9DDE09336856}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1683308C-36D4-49B1-8CCE-9DDE09336856}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1683308C-36D4-49B1-8CCE-9DDE09336856}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1683308C-36D4-49B1-8CCE-9DDE09336856}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -163,6 +169,7 @@ Global {1D6B1BA7-496F-4F91-A115-EF5E5DC6E6C2} = {A431DCB4-6EF9-4BEF-8902-FA704D62624E} {4166AC73-6969-406A-ADD0-67CB70A76D9C} = {A431DCB4-6EF9-4BEF-8902-FA704D62624E} {5DC793B1-F82B-4BC7-99C9-FE8C1545E1F7} = {A431DCB4-6EF9-4BEF-8902-FA704D62624E} + {1683308C-36D4-49B1-8CCE-9DDE09336856} = {A431DCB4-6EF9-4BEF-8902-FA704D62624E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7DA0BB43-C1D4-4688-BE43-A9ED2D6F78EE} diff --git a/test/BitMono.Core.Tests/BitMono.Core.Tests.csproj b/test/BitMono.Core.Tests/BitMono.Core.Tests.csproj index 3ac31359..be759e98 100644 --- a/test/BitMono.Core.Tests/BitMono.Core.Tests.csproj +++ b/test/BitMono.Core.Tests/BitMono.Core.Tests.csproj @@ -1,42 +1,42 @@  - - net6.0 - 10 - + + net6.0 + 10 + - - false - none - + + false + none + - - false - none - + + false + none + - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + - - - - - - - - - + + + + + + + + + From c7326738c590331f31495cce4cb8daa2a47f4f7e Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:47:11 +0200 Subject: [PATCH 07/13] Feature pre-implementation --- .../Extensions/ProtectionExtensions.cs | 13 ++++++++++ .../Attributes/DependOnRuntimeAttribute.cs | 12 +++++++++ .../Protecting/Attributes/RuntimeMoniker.cs | 6 +++++ src/BitMono.Obfuscation/BitMonoObfuscator.cs | 26 +++++++++++++++++++ src/BitMono.Obfuscation/GlobalUsings.cs | 1 + src/BitMono.Protections/BitDotNet.cs | 2 +- src/BitMono.Protections/CallToCalli.cs | 4 +-- 7 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs create mode 100644 src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs diff --git a/src/BitMono.Core/Extensions/ProtectionExtensions.cs b/src/BitMono.Core/Extensions/ProtectionExtensions.cs index 4b2a048a..4a1645c6 100644 --- a/src/BitMono.Core/Extensions/ProtectionExtensions.cs +++ b/src/BitMono.Core/Extensions/ProtectionExtensions.cs @@ -23,6 +23,19 @@ public static bool TryGetDoNotResolveAttribute(out DoNotResolveAttr { return typeof(TProtection).TryGetDoNotResolveAttribute(out attribute); } + public static bool TryGetDependOnRuntimeAttribute(this Type source, out DependOnRuntimeAttribute? attribute, bool inherit = false) + { + attribute = source.GetCustomAttribute(inherit); + if (attribute == null) + { + return false; + } + return true; + } + public static bool TryGetDependOnRuntimeAttribute(this IProtection source, out DependOnRuntimeAttribute? attribute) + { + return source.GetType().TryGetDependOnRuntimeAttribute(out attribute); + } public static string GetName(this Type source, bool inherit = false) { var protectionNameAttribute = source.GetCustomAttribute(inherit); diff --git a/src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs b/src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs new file mode 100644 index 00000000..0b346999 --- /dev/null +++ b/src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs @@ -0,0 +1,12 @@ +namespace BitMono.Core.Protecting.Attributes; + +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +public class DependOnRuntimeAttribute : Attribute +{ + public DependOnRuntimeAttribute(RuntimeMoniker runtimeMoniker) + { + RuntimeMoniker = runtimeMoniker; + } + + public RuntimeMoniker RuntimeMoniker { get; } +} \ No newline at end of file diff --git a/src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs b/src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs new file mode 100644 index 00000000..f1ffe264 --- /dev/null +++ b/src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs @@ -0,0 +1,6 @@ +namespace BitMono.Core.Protecting.Attributes; + +public enum RuntimeMoniker +{ + Mono +} \ No newline at end of file diff --git a/src/BitMono.Obfuscation/BitMonoObfuscator.cs b/src/BitMono.Obfuscation/BitMonoObfuscator.cs index 52e093d5..facafa37 100644 --- a/src/BitMono.Obfuscation/BitMonoObfuscator.cs +++ b/src/BitMono.Obfuscation/BitMonoObfuscator.cs @@ -2,6 +2,32 @@ #pragma warning disable CS8618 namespace BitMono.Obfuscation; +public interface IProtectionRunner +{ + Task Run(IProtection protection, ProtectionContext context, ProtectionParameters parameters); +} +public class ProtectionRuntimeMonikerRunner : IProtectionRunner +{ + public async Task Run(IProtection protection, ProtectionContext context, ProtectionParameters parameters) + { + if (protection.TryGetDependOnRuntimeAttribute(out var attribute)) + { + var runtimeInfo = RuntimeUtilities.GetFrameworkInformation(); + if (attribute.RuntimeMoniker == RuntimeMoniker.Mono && runtimeInfo.HasMono) + { + await protection.ExecuteAsync(context, parameters); + } + } + } +} +public class ProtectionRunner : IProtectionRunner +{ + public async Task Run(IProtection protection, ProtectionContext context, ProtectionParameters parameters) + { + await protection.ExecuteAsync(context, parameters); + } +} + public class BitMonoObfuscator { private readonly ProtectionContext m_Context; diff --git a/src/BitMono.Obfuscation/GlobalUsings.cs b/src/BitMono.Obfuscation/GlobalUsings.cs index 95620809..3d6bb32b 100644 --- a/src/BitMono.Obfuscation/GlobalUsings.cs +++ b/src/BitMono.Obfuscation/GlobalUsings.cs @@ -25,5 +25,6 @@ global using System.Text; global using System.Threading; global using System.Threading.Tasks; +global using BitMono.Core.Protecting.Attributes; global using Pocket.Extensions; global using ILogger = Serilog.ILogger; \ No newline at end of file diff --git a/src/BitMono.Protections/BitDotNet.cs b/src/BitMono.Protections/BitDotNet.cs index fee4152e..ed527528 100644 --- a/src/BitMono.Protections/BitDotNet.cs +++ b/src/BitMono.Protections/BitDotNet.cs @@ -19,7 +19,7 @@ public Task ExecuteAsync(ProtectionContext context, ProtectionParameters paramet stream.Position += 0x10; var x64PEOptionsHeader = reader.ReadUInt16() == 0x20B; - + stream.Position += x64PEOptionsHeader ? 0x38 : 0x28 + 0xA6; var dotNetVirtualAddress = reader.ReadUInt32(); diff --git a/src/BitMono.Protections/CallToCalli.cs b/src/BitMono.Protections/CallToCalli.cs index 5d33926e..ffc6f95d 100644 --- a/src/BitMono.Protections/CallToCalli.cs +++ b/src/BitMono.Protections/CallToCalli.cs @@ -1,7 +1,7 @@ -#pragma warning disable CS8602 -namespace BitMono.Protections; +namespace BitMono.Protections; [DoNotResolve(MemberInclusionFlags.SpecialRuntime)] +[DependOnRuntime(RuntimeMoniker.NotMono)] public class CallToCalli : IProtection { public Task ExecuteAsync(ProtectionContext context, ProtectionParameters parameters) From 6a7a10d073a1ddc89791881c592c09ad545c9cc1 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Sat, 11 Feb 2023 13:14:37 +0200 Subject: [PATCH 08/13] Implement feature and bug fix with x2 protections output info --- src/BitMono.CLI/Program.cs | 5 ++- .../EnvironmentRuntimeInformation.cs | 4 +- .../Extensions/ProtectionExtensions.cs | 21 +++++++-- .../SerilogContextCallerExtensions.cs | 14 ------ src/BitMono.Core/GlobalUsings.cs | 1 + .../Analyzing/ReflectionCriticalAnalyzer.cs | 3 +- .../Attributes/DependOnRuntimeAttribute.cs | 12 ------ .../Attributes/KnownRuntimeMonikers.cs | 6 +++ .../Protecting/Attributes/RuntimeMoniker.cs | 6 --- .../Attributes/RuntimeMonikerAttribute.cs | 18 ++++++++ .../Attributes/RuntimeMonikerMonoAttribute.cs | 9 ++++ .../Resolvers/DoNotResolveMemberResolver.cs | 2 +- .../Resolvers/ProtectionsResolver.cs | 7 +-- .../BitMonoProtectionsConfiguration.cs | 2 +- .../AutofacServiceProviderExtensions.cs | 6 +-- src/BitMono.Host/obfuscation.json | 20 +++++---- src/BitMono.Host/protections.json | 4 +- src/BitMono.Obfuscation/BitMonoEngine.cs | 9 +++- src/BitMono.Obfuscation/BitMonoObfuscator.cs | 30 +------------ .../DependenciesDataResolver.cs | 3 +- src/BitMono.Obfuscation/GlobalUsings.cs | 1 + .../ObfuscationAttributesStripNotifier.cs | 2 +- .../ProtectionsNotifier.cs | 12 ++++-- .../ProtectionsRuntimeMonikerNotifier.cs | 43 +++++++++++++++++++ src/BitMono.Obfuscation/ProtectionsSorter.cs | 26 +++++++---- src/BitMono.Protections/AntiDecompiler.cs | 1 + src/BitMono.Protections/BitDotNet.cs | 1 + src/BitMono.Protections/BitMono.cs | 1 + src/BitMono.Protections/BitTimeDateStamp.cs | 1 + src/BitMono.Protections/CallToCalli.cs | 4 +- src/BitMono.Protections/GlobalUsings.cs | 1 + src/BitMono.Shared/Models/Obfuscation.cs | 1 + 32 files changed, 167 insertions(+), 109 deletions(-) delete mode 100644 src/BitMono.Core/Extensions/SerilogContextCallerExtensions.cs delete mode 100644 src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs create mode 100644 src/BitMono.Core/Protecting/Attributes/KnownRuntimeMonikers.cs delete mode 100644 src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs create mode 100644 src/BitMono.Core/Protecting/Attributes/RuntimeMonikerAttribute.cs create mode 100644 src/BitMono.Core/Protecting/Attributes/RuntimeMonikerMonoAttribute.cs create mode 100644 src/BitMono.Obfuscation/ProtectionsRuntimeMonikerNotifier.cs diff --git a/src/BitMono.CLI/Program.cs b/src/BitMono.CLI/Program.cs index d15ee0bb..890424b0 100644 --- a/src/BitMono.CLI/Program.cs +++ b/src/BitMono.CLI/Program.cs @@ -1,4 +1,5 @@ -namespace BitMono.CLI; +#pragma warning disable CS8604 +namespace BitMono.CLI; internal class Program { @@ -33,7 +34,7 @@ private static async Task Main(string[] args) .ToList(); var logger = serviceProvider.LifetimeScope .Resolve() - .ForContextFile(); + .ForContext(); var cancellationTokenSource = new CancellationTokenSource(); var engine = new BitMonoEngine(obfuscationAttributeResolver, obfuscateAssemblyAttributeResolver, diff --git a/src/BitMono.Core/Extensions/EnvironmentRuntimeInformation.cs b/src/BitMono.Core/Extensions/EnvironmentRuntimeInformation.cs index eee8c2f9..f8652c42 100644 --- a/src/BitMono.Core/Extensions/EnvironmentRuntimeInformation.cs +++ b/src/BitMono.Core/Extensions/EnvironmentRuntimeInformation.cs @@ -5,13 +5,13 @@ public class EnvironmentRuntimeInformation public Version? NetFrameworkVersion { get; set; } public OperatingSystem? OperatingSystem { get; set; } public int? Bits { get; set; } - public bool? HasMono { get; set; } + public bool HasMono { get; set; } public Type? MonoType { get; set; } public string? MonoDisplayName { get; set; } public override string ToString() { return - $"Running on {OperatingSystem}, {(HasMono == false ? $"{DotNetRuntimeInfo.NetFramework} v{NetFrameworkVersion}" : MonoDisplayName)}, x{Bits} bits"; + $"Running on {OperatingSystem}, {(HasMono == false ? $"{DotNetRuntimeInfo.NetFramework} v{NetFrameworkVersion}" : $"Mono: {MonoDisplayName}")}, x{Bits} bits"; } } \ No newline at end of file diff --git a/src/BitMono.Core/Extensions/ProtectionExtensions.cs b/src/BitMono.Core/Extensions/ProtectionExtensions.cs index 4a1645c6..677b9294 100644 --- a/src/BitMono.Core/Extensions/ProtectionExtensions.cs +++ b/src/BitMono.Core/Extensions/ProtectionExtensions.cs @@ -23,18 +23,31 @@ public static bool TryGetDoNotResolveAttribute(out DoNotResolveAttr { return typeof(TProtection).TryGetDoNotResolveAttribute(out attribute); } - public static bool TryGetDependOnRuntimeAttribute(this Type source, out DependOnRuntimeAttribute? attribute, bool inherit = false) + public static bool TryGetRuntimeMonikerAttribute(this Type source, out RuntimeMonikerAttribute? attribute, bool inherit = false) { - attribute = source.GetCustomAttribute(inherit); + attribute = source.GetCustomAttribute(inherit); if (attribute == null) { return false; } return true; } - public static bool TryGetDependOnRuntimeAttribute(this IProtection source, out DependOnRuntimeAttribute? attribute) + public static bool TryGetRuntimeMonikerAttribute(this IProtection source, out RuntimeMonikerAttribute? attribute) { - return source.GetType().TryGetDependOnRuntimeAttribute(out attribute); + return source.GetType().TryGetRuntimeMonikerAttribute(out attribute); + } + public static bool TryGetObsoleteAttribute(this Type source, out ObsoleteAttribute? attribute, bool inherit = false) + { + attribute = source.GetCustomAttribute(inherit); + if (attribute == null) + { + return false; + } + return true; + } + public static bool TryGetObsoleteAttribute(this IProtection source, out ObsoleteAttribute? attribute) + { + return source.GetType().TryGetObsoleteAttribute(out attribute); } public static string GetName(this Type source, bool inherit = false) { diff --git a/src/BitMono.Core/Extensions/SerilogContextCallerExtensions.cs b/src/BitMono.Core/Extensions/SerilogContextCallerExtensions.cs deleted file mode 100644 index b2e04f02..00000000 --- a/src/BitMono.Core/Extensions/SerilogContextCallerExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace BitMono.Core.Extensions; - -public static class SerilogContextCallerExtensions -{ - private const string CsharpFileExtension = ".cs"; - public static ILogger ForContextFile(this ILogger source, [CallerFilePath] string caller = "") - { - caller = caller - .SplitToDirectorySeparators() - .Last() - .Replace(CsharpFileExtension, string.Empty); - return source.ForContext(Constants.SourceContextPropertyName, caller); - } -} \ No newline at end of file diff --git a/src/BitMono.Core/GlobalUsings.cs b/src/BitMono.Core/GlobalUsings.cs index 8282ddd0..e2a7f1ee 100644 --- a/src/BitMono.Core/GlobalUsings.cs +++ b/src/BitMono.Core/GlobalUsings.cs @@ -20,6 +20,7 @@ global using System; global using System.Collections.Generic; global using System.Diagnostics; +global using System.Diagnostics.CodeAnalysis; global using System.Linq; global using System.Reflection; global using System.Runtime.CompilerServices; diff --git a/src/BitMono.Core/Protecting/Analyzing/ReflectionCriticalAnalyzer.cs b/src/BitMono.Core/Protecting/Analyzing/ReflectionCriticalAnalyzer.cs index a4981872..aa23367d 100644 --- a/src/BitMono.Core/Protecting/Analyzing/ReflectionCriticalAnalyzer.cs +++ b/src/BitMono.Core/Protecting/Analyzing/ReflectionCriticalAnalyzer.cs @@ -34,7 +34,6 @@ public bool NotCriticalToMakeChanges(MethodDefinition method) if (method.CilMethodBody is { } body) { body.ConstructSymbolicFlowGraph(out var dataFlowGraph); - foreach (var node in dataFlowGraph.Nodes) { var orderedDependencies = @@ -42,7 +41,7 @@ public bool NotCriticalToMakeChanges(MethodDefinition method) foreach (var order in orderedDependencies) { var instruction = order.Contents; - if (instruction.OpCode.Code == CilCode.Call && instruction.Operand is IMethodDefOrRef calledMethod) + if (instruction?.OpCode.Code == CilCode.Call && instruction.Operand is IMethodDefOrRef calledMethod) { if (IsReflection(calledMethod)) { diff --git a/src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs b/src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs deleted file mode 100644 index 0b346999..00000000 --- a/src/BitMono.Core/Protecting/Attributes/DependOnRuntimeAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace BitMono.Core.Protecting.Attributes; - -[AttributeUsage(AttributeTargets.Class, Inherited = false)] -public class DependOnRuntimeAttribute : Attribute -{ - public DependOnRuntimeAttribute(RuntimeMoniker runtimeMoniker) - { - RuntimeMoniker = runtimeMoniker; - } - - public RuntimeMoniker RuntimeMoniker { get; } -} \ No newline at end of file diff --git a/src/BitMono.Core/Protecting/Attributes/KnownRuntimeMonikers.cs b/src/BitMono.Core/Protecting/Attributes/KnownRuntimeMonikers.cs new file mode 100644 index 00000000..7275f8f9 --- /dev/null +++ b/src/BitMono.Core/Protecting/Attributes/KnownRuntimeMonikers.cs @@ -0,0 +1,6 @@ +namespace BitMono.Core.Protecting.Attributes; + +public static class KnownRuntimeMonikers +{ + public const string Mono = nameof(Mono); +} \ No newline at end of file diff --git a/src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs b/src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs deleted file mode 100644 index f1ffe264..00000000 --- a/src/BitMono.Core/Protecting/Attributes/RuntimeMoniker.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace BitMono.Core.Protecting.Attributes; - -public enum RuntimeMoniker -{ - Mono -} \ No newline at end of file diff --git a/src/BitMono.Core/Protecting/Attributes/RuntimeMonikerAttribute.cs b/src/BitMono.Core/Protecting/Attributes/RuntimeMonikerAttribute.cs new file mode 100644 index 00000000..e746e6ef --- /dev/null +++ b/src/BitMono.Core/Protecting/Attributes/RuntimeMonikerAttribute.cs @@ -0,0 +1,18 @@ +namespace BitMono.Core.Protecting.Attributes; + +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] +public abstract class RuntimeMonikerAttribute : Attribute +{ + protected RuntimeMonikerAttribute(string name) + { + Name = name; + } + + public string Name { get; } + + public virtual string GetMessage() + { + return $"Intended for {Name} runtime"; + } +} \ No newline at end of file diff --git a/src/BitMono.Core/Protecting/Attributes/RuntimeMonikerMonoAttribute.cs b/src/BitMono.Core/Protecting/Attributes/RuntimeMonikerMonoAttribute.cs new file mode 100644 index 00000000..e6d14667 --- /dev/null +++ b/src/BitMono.Core/Protecting/Attributes/RuntimeMonikerMonoAttribute.cs @@ -0,0 +1,9 @@ +namespace BitMono.Core.Protecting.Attributes; + +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +public class RuntimeMonikerMonoAttribute : RuntimeMonikerAttribute +{ + public RuntimeMonikerMonoAttribute() : base(KnownRuntimeMonikers.Mono) + { + } +} \ No newline at end of file diff --git a/src/BitMono.Core/Protecting/Resolvers/DoNotResolveMemberResolver.cs b/src/BitMono.Core/Protecting/Resolvers/DoNotResolveMemberResolver.cs index d1f09e3b..ba04837c 100644 --- a/src/BitMono.Core/Protecting/Resolvers/DoNotResolveMemberResolver.cs +++ b/src/BitMono.Core/Protecting/Resolvers/DoNotResolveMemberResolver.cs @@ -7,7 +7,7 @@ public class DoNotResolveMemberResolver : IMemberResolver private readonly ReflectionCriticalAnalyzer m_ReflectionCriticalAnalyzer; public DoNotResolveMemberResolver( - RuntimeCriticalAnalyzer runtimeCriticalAnalyzer, + RuntimeCriticalAnalyzer runtimeCriticalAnalyzer, ModelAttributeCriticalAnalyzer modelAttributeCriticalAnalyzer, ReflectionCriticalAnalyzer reflectionCriticalAnalyzer) { diff --git a/src/BitMono.Core/Protecting/Resolvers/ProtectionsResolver.cs b/src/BitMono.Core/Protecting/Resolvers/ProtectionsResolver.cs index 0cfd1ecb..ae7930c0 100644 --- a/src/BitMono.Core/Protecting/Resolvers/ProtectionsResolver.cs +++ b/src/BitMono.Core/Protecting/Resolvers/ProtectionsResolver.cs @@ -15,7 +15,6 @@ public ProtectionsResolve Sort() { var foundProtections = new List(); var cachedProtections = m_Protections.ToArray().ToList(); - var disabledProtections = new List(); var unknownProtections = new List(); foreach (var protectionSettings in m_ProtectionSettings.Where(p => p.Enabled)) { @@ -30,11 +29,7 @@ public ProtectionsResolve Sort() unknownProtections.Add(protectionSettings.Name); } } - for (var i = 0; i < cachedProtections.Count; i++) - { - var protection = cachedProtections[i]; - disabledProtections.Add(protection.GetName()); - } + var disabledProtections = cachedProtections.Select(protection => protection.GetName()).ToList(); return new ProtectionsResolve { FoundProtections = foundProtections, diff --git a/src/BitMono.Host/Configurations/BitMonoProtectionsConfiguration.cs b/src/BitMono.Host/Configurations/BitMonoProtectionsConfiguration.cs index cfc51ec9..a650027d 100644 --- a/src/BitMono.Host/Configurations/BitMonoProtectionsConfiguration.cs +++ b/src/BitMono.Host/Configurations/BitMonoProtectionsConfiguration.cs @@ -2,7 +2,7 @@ public class BitMonoProtectionsConfiguration : JsonConfigurationAccessor, IBitMonoProtectionsConfiguration { - public BitMonoProtectionsConfiguration() : base("protections.json") + public BitMonoProtectionsConfiguration(string? file = null) : base(file ?? "protections.json") { } } \ No newline at end of file diff --git a/src/BitMono.Host/Extensions/AutofacServiceProviderExtensions.cs b/src/BitMono.Host/Extensions/AutofacServiceProviderExtensions.cs index 4c2a4496..f1bc9a82 100644 --- a/src/BitMono.Host/Extensions/AutofacServiceProviderExtensions.cs +++ b/src/BitMono.Host/Extensions/AutofacServiceProviderExtensions.cs @@ -2,13 +2,13 @@ namespace BitMono.Host.Extensions; [SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")] +[SuppressMessage("ReSharper", "IdentifierTypo")] public static class AutofacServiceProviderExtensions { private static readonly string ProtectionsFileName = $"{typeof(BitMono.Protections.BitMono).Namespace}.dll"; public static ContainerBuilder AddProtections(this ContainerBuilder source, string? file = null) { - var rawData = File.ReadAllBytes(file ?? ProtectionsFileName); - Assembly.Load(rawData); + File.ReadAllBytes(file ?? ProtectionsFileName); // No need to Assembly.Load(rawData) the byte[], perhaps a bug of .NET Framework var assemblies = AppDomain.CurrentDomain.GetAssemblies(); source.RegisterAssemblyTypes(assemblies) @@ -22,7 +22,7 @@ public static ContainerBuilder AddProtections(this ContainerBuilder source, stri public static ServiceCollection AddConfigurations(this ServiceCollection source, string? protectionsFile = null, string? criticalsFile = null, string? obfuscationFile = null) { - var protections = new BitMonoProtectionsConfiguration(); + var protections = new BitMonoProtectionsConfiguration(protectionsFile); var criticals = new BitMonoCriticalsConfiguration(criticalsFile); var obfuscation = new BitMonoObfuscationConfiguration(obfuscationFile); source.AddOptions() diff --git a/src/BitMono.Host/obfuscation.json b/src/BitMono.Host/obfuscation.json index b36ede92..e2acb083 100644 --- a/src/BitMono.Host/obfuscation.json +++ b/src/BitMono.Host/obfuscation.json @@ -11,35 +11,35 @@ // Set to true indicates whether enabled "NoInliningMethodObfuscationExclude": true, - // Exclude from obfuscation if type/method has [ObfuscationAttribute(..)] + // Exclude from obfuscation if type/method has [ObfuscationAttribute(..)] // should have an [Obfuscation(Feature = "Name")] attribute with Protection name known as Feature // Set to true indicates whether enabled "ObfuscationAttributeObfuscationExclude": true, - // Exclude from obfuscation if assembly has [ObfuscateAssemblyAttribute(true)] + // Exclude from obfuscation if assembly has [ObfuscateAssemblyAttribute(true)] // Set to true indicates whether enabled "ObfuscateAssemblyAttributeObfuscationExclude": true, - - // Exclude from obfuscation if member name used by: + + // Exclude from obfuscation if member name used by: // Type.GetMethod, Type.GetField, Type.GetProperty, Type.GetEvent, Type.GetMember // Set to true indicates whether enabled "ReflectionMembersObfuscationExclude": true, - // Strip attribute after obfuscation if assembly has [ObfuscateAssemblyAttribute(true, StripAfterObfuscation = true)] + // Strip attribute after obfuscation if assembly has [ObfuscateAssemblyAttribute(true, StripAfterObfuscation = true)] // or member has [Obfuscation(Feature = "Some_BitMono_Feature", StripAfterObfuscation = true] // By default, you could just specify [Obfuscation(Feature = "Some_BitMono_Feature"] - and this will strip it // (StripAfterObfuscation is true by default in dotnet sources), the same with ObfuscateAssemblyAttribute // Set to true indicates whether enabled "StripObfuscationAttributes": true, - // Output errors that were registered while building the PE image. BitMono feature is that - // being used vulnerabilities of decompilers and Mono and this is the most powerful of them, + // Output errors that were registered while building the PE image. BitMono feature is that + // being used vulnerabilities of decompilers and Mono and this is the most powerful of them, // decompilers and other tools could think that this is cannot work fine and because of that some weird errors // can be outputted // Set to true indicates whether enabled "OutputPEImageBuildErrors": true, - // Sometimes when you don't have needed dependency for your app, a tons of reasons could be for that, + // Sometimes when you don't have needed dependency for your app, a tons of reasons could be for that, // if you got an error that says you don't have needed dependency first of all at least try to add this dependency // otherwise if this is deprecated - you can set this as false to ignore error and continue obfuscation // NB! but be aware of kind a weird errors and issues that breaking you app, and it stops working after that @@ -48,6 +48,10 @@ // Stay it true to stay enabled if this is possible! "FailOnNoRequiredDependency": false, + // Output warnings saying that protection is intended for specific runtime + // Set to true indicates whether enabled + "OutputRuntimeMonikerWarnings": true, + // Opens directory with protected file in file explorer in top of the screen, if set to true "OpenFileDestinationInFileExplorer": true, diff --git a/src/BitMono.Host/protections.json b/src/BitMono.Host/protections.json index cdd73a85..a32778f7 100644 --- a/src/BitMono.Host/protections.json +++ b/src/BitMono.Host/protections.json @@ -26,7 +26,7 @@ }, { "Name": "StringsEncryption", - "Enabled": true + "Enabled": false }, { "Name": "DotNetHook", @@ -50,7 +50,7 @@ }, { "Name": "BitDotNet", - "Enabled": false + "Enabled": true }, { "Name": "BitMono", diff --git a/src/BitMono.Obfuscation/BitMonoEngine.cs b/src/BitMono.Obfuscation/BitMonoEngine.cs index 392c516f..ad540554 100644 --- a/src/BitMono.Obfuscation/BitMonoEngine.cs +++ b/src/BitMono.Obfuscation/BitMonoEngine.cs @@ -1,5 +1,10 @@ -namespace BitMono.Obfuscation; +#pragma warning disable CS8602 +#pragma warning disable CS8604 +namespace BitMono.Obfuscation; +[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] +[SuppressMessage("ReSharper", "IdentifierTypo")] +[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] public class BitMonoEngine { private readonly ObfuscationAttributeResolver m_ObfuscationAttributeResolver; @@ -25,7 +30,7 @@ public BitMonoEngine( m_ProtectionSettings = protectionSetting; m_MemberResolvers = memberResolvers; m_Protections = protections; - m_Logger = logger.ForContextFile(); + m_Logger = logger.ForContext(); } internal async Task StartAsync(ProtectionContext context, IDataWriter dataWriter) diff --git a/src/BitMono.Obfuscation/BitMonoObfuscator.cs b/src/BitMono.Obfuscation/BitMonoObfuscator.cs index facafa37..61a9f1da 100644 --- a/src/BitMono.Obfuscation/BitMonoObfuscator.cs +++ b/src/BitMono.Obfuscation/BitMonoObfuscator.cs @@ -1,33 +1,7 @@ #pragma warning disable CS8604 -#pragma warning disable CS8618 +#pragma warning disable CS8602 namespace BitMono.Obfuscation; -public interface IProtectionRunner -{ - Task Run(IProtection protection, ProtectionContext context, ProtectionParameters parameters); -} -public class ProtectionRuntimeMonikerRunner : IProtectionRunner -{ - public async Task Run(IProtection protection, ProtectionContext context, ProtectionParameters parameters) - { - if (protection.TryGetDependOnRuntimeAttribute(out var attribute)) - { - var runtimeInfo = RuntimeUtilities.GetFrameworkInformation(); - if (attribute.RuntimeMoniker == RuntimeMoniker.Mono && runtimeInfo.HasMono) - { - await protection.ExecuteAsync(context, parameters); - } - } - } -} -public class ProtectionRunner : IProtectionRunner -{ - public async Task Run(IProtection protection, ProtectionContext context, ProtectionParameters parameters) - { - await protection.ExecuteAsync(context, parameters); - } -} - public class BitMonoObfuscator { private readonly ProtectionContext m_Context; @@ -64,7 +38,7 @@ public BitMonoObfuscator( m_ObfuscationAttributeResolver = obfuscationAttributeResolver; m_ObfuscateAssemblyAttributeResolver = obfuscateAssemblyAttributeResolver; m_Obfuscation = obfuscation; - m_Logger = logger.ForContextFile(); + m_Logger = logger.ForContext(); m_InvokablePipeline = new InvokablePipeline(m_Context); m_MemberResolver = new MembersResolver(); m_ProtectionExecutionNotifier = new ProtectionExecutionNotifier(m_Logger); diff --git a/src/BitMono.Obfuscation/DependenciesDataResolver.cs b/src/BitMono.Obfuscation/DependenciesDataResolver.cs index cb0daa27..f8afbb3a 100644 --- a/src/BitMono.Obfuscation/DependenciesDataResolver.cs +++ b/src/BitMono.Obfuscation/DependenciesDataResolver.cs @@ -9,10 +9,11 @@ public DependenciesDataResolver(string dependenciesDirectoryName) m_DependenciesDirectoryName = dependenciesDirectoryName; } + [SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")] public IEnumerable Resolve() { var dependencies = Directory.GetFiles(m_DependenciesDirectoryName); - for (int i = 0; i < dependencies.Length; i++) + for (var i = 0; i < dependencies.Length; i++) { yield return File.ReadAllBytes(dependencies[i]); } diff --git a/src/BitMono.Obfuscation/GlobalUsings.cs b/src/BitMono.Obfuscation/GlobalUsings.cs index 3d6bb32b..a9efab9c 100644 --- a/src/BitMono.Obfuscation/GlobalUsings.cs +++ b/src/BitMono.Obfuscation/GlobalUsings.cs @@ -26,5 +26,6 @@ global using System.Threading; global using System.Threading.Tasks; global using BitMono.Core.Protecting.Attributes; +global using Microsoft.Extensions.Options; global using Pocket.Extensions; global using ILogger = Serilog.ILogger; \ No newline at end of file diff --git a/src/BitMono.Obfuscation/ObfuscationAttributesStripNotifier.cs b/src/BitMono.Obfuscation/ObfuscationAttributesStripNotifier.cs index 4427d259..99145ce0 100644 --- a/src/BitMono.Obfuscation/ObfuscationAttributesStripNotifier.cs +++ b/src/BitMono.Obfuscation/ObfuscationAttributesStripNotifier.cs @@ -7,7 +7,7 @@ public class ObfuscationAttributesStripNotifier public ObfuscationAttributesStripNotifier(ILogger logger) { - m_Logger = logger.ForContextFile(); + m_Logger = logger.ForContext(); } public void Notify(ObfuscationAttributesStrip obfuscationAttributesStrip) diff --git a/src/BitMono.Obfuscation/ProtectionsNotifier.cs b/src/BitMono.Obfuscation/ProtectionsNotifier.cs index 4872a2ec..24209a7c 100644 --- a/src/BitMono.Obfuscation/ProtectionsNotifier.cs +++ b/src/BitMono.Obfuscation/ProtectionsNotifier.cs @@ -1,4 +1,5 @@ -namespace BitMono.Obfuscation; +#pragma warning disable CS8602 +namespace BitMono.Obfuscation; public class ProtectionsNotifier { @@ -8,9 +9,10 @@ public class ProtectionsNotifier public ProtectionsNotifier(Shared.Models.Obfuscation obfuscation, ILogger logger) { m_Obfuscation = obfuscation; - m_Logger = logger.ForContextFile(); + m_Logger = logger.ForContext(); } + [SuppressMessage("ReSharper", "InvertIf")] [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] public void Notify(ProtectionsSort protectionsSort) { @@ -19,7 +21,7 @@ public void Notify(ProtectionsSort protectionsSort) if (protectionsSort.HasProtections) { var stringBuilder = new StringBuilder(); - stringBuilder.Append(string.Join(", ", protectionsSort.SortedProtections.Select(p => p.GetName()))); + stringBuilder.Append(string.Join(", ", protectionsSort.SortedProtections.Select(p => $"{p.GetName()}"))); if (protectionsSort.Pipelines.Any()) { stringBuilder.Append(", "); @@ -31,12 +33,14 @@ public void Notify(ProtectionsSort protectionsSort) stringBuilder.Append(string.Join(", ", protectionsSort.Packers.Select(p => p.GetName()))); } m_Logger.Information("Enabled protections: {0}", stringBuilder.ToString()); + var runtimeMonikerNotifier = new ProtectionsRuntimeMonikerNotifier(m_Obfuscation, m_Logger); + runtimeMonikerNotifier.Notify(protectionsSort); } if (protectionsSort.DeprecatedProtections.Any()) { m_Logger.Warning("Skip deprecated protections: {0}", string.Join(", ", protectionsSort.DeprecatedProtections.Select(p => p?.GetName()))); } - if (protectionsSort.ProtectionsResolve!.DisabledProtections.Any()) + if (protectionsSort.ProtectionsResolve.DisabledProtections.Any()) { m_Logger.Warning("Disabled protections: {0}", string.Join(", ", protectionsSort.ProtectionsResolve.DisabledProtections.Select(p => p ?? "Unnamed Protection"))); } diff --git a/src/BitMono.Obfuscation/ProtectionsRuntimeMonikerNotifier.cs b/src/BitMono.Obfuscation/ProtectionsRuntimeMonikerNotifier.cs new file mode 100644 index 00000000..df7e932b --- /dev/null +++ b/src/BitMono.Obfuscation/ProtectionsRuntimeMonikerNotifier.cs @@ -0,0 +1,43 @@ +#pragma warning disable CS8602 +namespace BitMono.Obfuscation; + +public class ProtectionsRuntimeMonikerNotifier +{ + private readonly Shared.Models.Obfuscation m_Obfuscation; + private readonly ILogger m_Logger; + + public ProtectionsRuntimeMonikerNotifier(Shared.Models.Obfuscation obfuscation, ILogger logger) + { + m_Obfuscation = obfuscation; + m_Logger = logger.ForContext(); + } + + [SuppressMessage("ReSharper", "InvertIf")] + public void Notify(ProtectionsSort protectionsSort) + { + if (m_Obfuscation.OutputRuntimeMonikerWarnings) + { + foreach (var protection in protectionsSort.SortedProtections) + { + if (protection.TryGetRuntimeMonikerAttribute(out var attribute)) + { + m_Logger.Warning("[!!!] {Name} - " + attribute.GetMessage(), protection.GetName()); + } + } + foreach (var protection in protectionsSort.Pipelines) + { + if (protection.TryGetRuntimeMonikerAttribute(out var attribute)) + { + m_Logger.Warning("[!!!] {Name} - " + attribute.GetMessage(), protection.GetName()); + } + } + foreach (var protection in protectionsSort.Packers) + { + if (protection.TryGetRuntimeMonikerAttribute(out var attribute)) + { + m_Logger.Warning("[!!!] {Name} - " + attribute.GetMessage(), protection.GetName()); + } + } + } + } +} \ No newline at end of file diff --git a/src/BitMono.Obfuscation/ProtectionsSorter.cs b/src/BitMono.Obfuscation/ProtectionsSorter.cs index 73ddad4a..6c98d35e 100644 --- a/src/BitMono.Obfuscation/ProtectionsSorter.cs +++ b/src/BitMono.Obfuscation/ProtectionsSorter.cs @@ -11,20 +11,28 @@ public ProtectionsSorter(ObfuscationAttributeResolver obfuscationAttributeResolv m_Assembly = assembly; } + [SuppressMessage("ReSharper", "PossibleMultipleEnumeration")] public ProtectionsSort Sort(List protections, IEnumerable protectionSettings) { - var protectionsResolve = new ProtectionsResolver(protections, protectionSettings).Sort(); - var obfuscationAttributeProtections = protectionsResolve.FoundProtections.Where(p => m_ObfuscationAttributeResolver.Resolve(p.GetName(), m_Assembly)); - var deprecatedProtections = protectionsResolve.FoundProtections.Where(p => p.GetType().GetCustomAttribute(false) != null); - var sortedProtections = protectionsResolve.FoundProtections.Except(obfuscationAttributeProtections) + var protectionsResolve = new ProtectionsResolver(protections, protectionSettings) + .Sort(); + var obfuscationAttributeProtections = + protectionsResolve.FoundProtections.Where(p => + m_ObfuscationAttributeResolver.Resolve(p.GetName(), m_Assembly)); + var deprecatedProtections = + protectionsResolve.FoundProtections.Where(p => p.TryGetObsoleteAttribute(out _)); + var sortedProtections = protectionsResolve.FoundProtections + .Except(obfuscationAttributeProtections) .Except(deprecatedProtections); - - var pipelineProtections = sortedProtections.Where(p => p is IPipelineProtection) + var pipelineProtections = sortedProtections + .Where(p => p is IPipelineProtection) .Cast(); - var packers = sortedProtections.Where(p => p is IPacker) + var packers = sortedProtections + .Where(p => p is IPacker) .Cast(); - - sortedProtections = sortedProtections.Except(packers).Except(pipelineProtections); + sortedProtections = sortedProtections + .Except(packers) + .Except(pipelineProtections); var hasProtections = sortedProtections.IsEmpty() == false || packers.IsEmpty() == false; return new ProtectionsSort diff --git a/src/BitMono.Protections/AntiDecompiler.cs b/src/BitMono.Protections/AntiDecompiler.cs index 7c964fd8..dbce3717 100644 --- a/src/BitMono.Protections/AntiDecompiler.cs +++ b/src/BitMono.Protections/AntiDecompiler.cs @@ -1,5 +1,6 @@ namespace BitMono.Protections; +[RuntimeMonikerMono] public class AntiDecompiler : IPipelineProtection { public Task ExecuteAsync(ProtectionContext context, ProtectionParameters parameters) diff --git a/src/BitMono.Protections/BitDotNet.cs b/src/BitMono.Protections/BitDotNet.cs index ed527528..09a204d9 100644 --- a/src/BitMono.Protections/BitDotNet.cs +++ b/src/BitMono.Protections/BitDotNet.cs @@ -1,5 +1,6 @@ namespace BitMono.Protections; +[RuntimeMonikerMono] public class BitDotNet : IPacker { private const int PEHeaderWithExtraByteHex = 0x00014550; diff --git a/src/BitMono.Protections/BitMono.cs b/src/BitMono.Protections/BitMono.cs index 283c0c68..355d54d4 100644 --- a/src/BitMono.Protections/BitMono.cs +++ b/src/BitMono.Protections/BitMono.cs @@ -1,5 +1,6 @@ namespace BitMono.Protections; +[RuntimeMonikerMono] public class BitMono : IPacker { public Task ExecuteAsync(ProtectionContext context, ProtectionParameters parameters) diff --git a/src/BitMono.Protections/BitTimeDateStamp.cs b/src/BitMono.Protections/BitTimeDateStamp.cs index b2636a42..654e6cbd 100644 --- a/src/BitMono.Protections/BitTimeDateStamp.cs +++ b/src/BitMono.Protections/BitTimeDateStamp.cs @@ -1,5 +1,6 @@ namespace BitMono.Protections; +[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] public class BitTimeDateStamp : IPacker { public Task ExecuteAsync(ProtectionContext context, ProtectionParameters parameters) diff --git a/src/BitMono.Protections/CallToCalli.cs b/src/BitMono.Protections/CallToCalli.cs index ffc6f95d..a7fb4869 100644 --- a/src/BitMono.Protections/CallToCalli.cs +++ b/src/BitMono.Protections/CallToCalli.cs @@ -1,9 +1,11 @@ namespace BitMono.Protections; [DoNotResolve(MemberInclusionFlags.SpecialRuntime)] -[DependOnRuntime(RuntimeMoniker.NotMono)] public class CallToCalli : IProtection { + [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] + [SuppressMessage("ReSharper", "PossibleNullReferenceException")] + [SuppressMessage("ReSharper", "InvertIf")] public Task ExecuteAsync(ProtectionContext context, ProtectionParameters parameters) { var runtimeMethodHandle = context.Importer.ImportType(typeof(RuntimeMethodHandle)).ToTypeSignature(isValueType: true); diff --git a/src/BitMono.Protections/GlobalUsings.cs b/src/BitMono.Protections/GlobalUsings.cs index 38221ead..38f7d364 100644 --- a/src/BitMono.Protections/GlobalUsings.cs +++ b/src/BitMono.Protections/GlobalUsings.cs @@ -14,6 +14,7 @@ global using BitMono.Utilities.Extensions.AsmResolver; global using System; global using System.Collections.Generic; +global using System.Diagnostics.CodeAnalysis; global using System.IO; global using System.Linq; global using System.Reflection; diff --git a/src/BitMono.Shared/Models/Obfuscation.cs b/src/BitMono.Shared/Models/Obfuscation.cs index fe7bf29c..7e1a3310 100644 --- a/src/BitMono.Shared/Models/Obfuscation.cs +++ b/src/BitMono.Shared/Models/Obfuscation.cs @@ -13,6 +13,7 @@ public class Obfuscation public bool StripObfuscationAttributes { get; set; } public bool OutputPEImageBuildErrors { get; set; } public bool FailOnNoRequiredDependency { get; set; } + public bool OutputRuntimeMonikerWarnings { get; set; } public bool OpenFileDestinationInFileExplorer { get; set; } public bool SpecificNamespacesObfuscationOnly { get; set; } public string[]? SpecificNamespaces { get; set; } From 6f0d21324f743d444858283e96cb78a469f1ad02 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Sat, 11 Feb 2023 13:26:37 +0200 Subject: [PATCH 09/13] Module refactoring --- src/BitMono.Host/Modules/BitMonoModule.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/BitMono.Host/Modules/BitMonoModule.cs b/src/BitMono.Host/Modules/BitMonoModule.cs index e46b6b29..ee3f24ec 100644 --- a/src/BitMono.Host/Modules/BitMonoModule.cs +++ b/src/BitMono.Host/Modules/BitMonoModule.cs @@ -5,6 +5,10 @@ public class BitMonoModule : Module private readonly Action? m_ConfigureContainer; private readonly Action? m_ConfigureServices; private readonly Action? m_ConfigureLogger; + private const string OutputTemplate = + "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}][{SourceContext}] {Message:lj}{NewLine}{Exception}"; + private const string LogsDirectoryName = "logs"; + private const string LogsFileName = "bitmono-{0:yyyy-MM-dd-HH-mm-ss}.log"; public BitMonoModule( Action? configureContainer = null, @@ -21,14 +25,14 @@ protected override void Load(ContainerBuilder containerBuilder) { m_ConfigureContainer?.Invoke(containerBuilder); - var logsPath = string.Format(Path.Combine("logs", "bitmono-{0:yyyy-MM-dd-HH-mm-ss}.log"), DateTime.Now) + var logsPath = string.Format(Path.Combine(LogsDirectoryName, LogsFileName), DateTime.Now) .ReplaceDirectorySeparatorToAlt(); var loggerConfiguration = new LoggerConfiguration() .Enrich.FromLogContext() .WriteTo.Async(configure => { configure.File(logsPath, rollingInterval: RollingInterval.Infinite, restrictedToMinimumLevel: LogEventLevel.Information, - outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}][{SourceContext}] {Message:lj}{NewLine}{Exception}"); + outputTemplate: OutputTemplate); }); if (m_ConfigureLogger != null) From 00591f56a6f72f775dc746b0825938774e69a5be Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Sat, 11 Feb 2023 14:11:08 +0200 Subject: [PATCH 10/13] Add new unit test for Reflection analysis --- test/BitMono.Core.Tests/GlobalUsings.cs | 1 + .../ReflectionCriticalAnalyzerTest.cs | 19 +++++++++++++++++++ .../GlobalUsings.cs | 1 + .../ReflectionMethods.cs | 9 +++++++++ 4 files changed, 30 insertions(+) create mode 100644 test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/GlobalUsings.cs diff --git a/test/BitMono.Core.Tests/GlobalUsings.cs b/test/BitMono.Core.Tests/GlobalUsings.cs index 7ac866dd..d32ea6cd 100644 --- a/test/BitMono.Core.Tests/GlobalUsings.cs +++ b/test/BitMono.Core.Tests/GlobalUsings.cs @@ -1,5 +1,6 @@ global using System.Collections; global using System.Collections.Generic; +global using System.Diagnostics.CodeAnalysis; global using System.Linq; global using AsmResolver.DotNet; global using BitMono.Core.Protecting.Analyzing; diff --git a/test/BitMono.Core.Tests/Protecting/Analyzing/ReflectionCriticalAnalyzerTest.cs b/test/BitMono.Core.Tests/Protecting/Analyzing/ReflectionCriticalAnalyzerTest.cs index 9633613c..3dee3350 100644 --- a/test/BitMono.Core.Tests/Protecting/Analyzing/ReflectionCriticalAnalyzerTest.cs +++ b/test/BitMono.Core.Tests/Protecting/Analyzing/ReflectionCriticalAnalyzerTest.cs @@ -18,4 +18,23 @@ public void WhenReflectionCriticalAnalyzing_AndMethodUsesReflectionOfItSelf_Then result.Should().BeFalse(); } + [Fact] + [SuppressMessage("ReSharper", "PossibleNullReferenceException")] + public void WhenReflectionCriticalAnalyzing_AndMethodUses2DifferentReflectionAnd1OnItSelf_ThenShouldBeFalseAndCountOfCachedMethodsShouldBe1AndMethodNameShouldBeEqualToSelf() + { + var module = ModuleDefinition.FromFile(typeof(ReflectionMethods).Assembly.Location); + var type = module.TopLevelTypes.First(t => t.Name == nameof(ReflectionMethods)); + var method = type.Methods.First(m => m.Name == nameof(ReflectionMethods.Uses3Reflection)); + var obfuscation = new Obfuscation + { + ReflectionMembersObfuscationExclude = true + }; + var criticalAnalyzer = new ReflectionCriticalAnalyzer(Options.Create(obfuscation)); + + var result = criticalAnalyzer.NotCriticalToMakeChanges(method); + + result.Should().BeFalse(); + criticalAnalyzer.CachedMethods.Count.Should().Be(1); + criticalAnalyzer.CachedMethods.First().Name.Value.Should().Be(method.Name); + } } \ No newline at end of file diff --git a/test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/GlobalUsings.cs b/test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/GlobalUsings.cs new file mode 100644 index 00000000..dbea1a41 --- /dev/null +++ b/test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/GlobalUsings.cs @@ -0,0 +1 @@ +global using System.Reflection; \ No newline at end of file diff --git a/test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/ReflectionMethods.cs b/test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/ReflectionMethods.cs index 11146d18..25d579c4 100644 --- a/test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/ReflectionMethods.cs +++ b/test/TestBinaries/DotNet/BitMono.Core.TestCases.Reflection/ReflectionMethods.cs @@ -2,8 +2,17 @@ namespace BitMono.Core.TestCases.Reflection; public class ReflectionMethods { + public static void VoidMethod(string text) + { + } public void UsesReflectionOnItSelf() { typeof(ReflectionMethods).GetMethod(nameof(UsesReflectionOnItSelf)); } + public void Uses3Reflection() + { + typeof(ReflectionMethods).GetMethod(nameof(Uses3Reflection)); + typeof(ReflectionMethods).GetMethod(nameof(UsesReflectionOnItSelf)); + typeof(ReflectionMethods).GetMethod(nameof(VoidMethod), BindingFlags.Public | BindingFlags.Static); + } } \ No newline at end of file From 562a908ef07eb5952f794fdb0e69c0b8249c0ba5 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Sat, 11 Feb 2023 16:21:20 +0200 Subject: [PATCH 11/13] Fix DotNetHook --- src/BitMono.Protections/DotNetHook.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/BitMono.Protections/DotNetHook.cs b/src/BitMono.Protections/DotNetHook.cs index b333a9ed..98ff3963 100644 --- a/src/BitMono.Protections/DotNetHook.cs +++ b/src/BitMono.Protections/DotNetHook.cs @@ -11,6 +11,8 @@ public DotNetHook(IRenamer renamer, RuntimeImplementations runtime) m_Random = runtime.Random; } + [SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")] + [SuppressMessage("ReSharper", "InvertIf")] public Task ExecuteAsync(ProtectionContext context, ProtectionParameters parameters) { var runtimeHookingType = context.RuntimeModule.ResolveOrThrow(typeof(Hooking)); @@ -37,7 +39,7 @@ public Task ExecuteAsync(ProtectionContext context, ProtectionParameters paramet { var callingMethod = callingOperandMethod.Resolve(); if (callingMethod is { CilMethodBody: { } } - && callingMethod.ParameterDefinitions.Any(p => p.IsIn || p.IsOut) == false) + && callingMethod.ParameterDefinitions.Any(p => p.IsIn || p.IsOut) == false && callingMethod.Managed) { if (context.Module.TryLookupMember(callingMethod.MetadataToken, out var callingMethodMetadata)) { @@ -50,8 +52,10 @@ public Task ExecuteAsync(ProtectionContext context, ProtectionParameters paramet var parameterDefinitions = callingMethod.ParameterDefinitions; for (var j = 0; j < parameterDefinitions.Count; j++) { - var parameter = parameterDefinitions[i]; - dummyMethod.ParameterDefinitions.Add(new ParameterDefinition(parameter.Sequence, parameter.Name, parameter.Attributes)); + var actualParameter = parameterDefinitions[j]; + var parameter = new ParameterDefinition(actualParameter.Sequence, + actualParameter.Name, actualParameter.Attributes); + dummyMethod.ParameterDefinitions.Add(parameter); } var dummyMethodBody = dummyMethod.CilMethodBody = new CilMethodBody(dummyMethod); if (callingMethod.Signature.ReturnsValue) @@ -59,7 +63,6 @@ public Task ExecuteAsync(ProtectionContext context, ProtectionParameters paramet dummyMethodBody.Instructions.Add(new CilInstruction(CilOpCodes.Ldnull)); } dummyMethodBody.Instructions.Add(new CilInstruction(CilOpCodes.Ret)); - var signature = MethodSignature.CreateStatic(systemVoid); var attributes = MethodAttributes.Assembly | MethodAttributes.Static; var initializationMethod = new MethodDefinition(m_Renamer.RenameUnsafely(), attributes, signature); From d42453ec4a7b96f086bb993b2f3cac3f96b920db Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Mon, 13 Feb 2023 10:21:09 +0200 Subject: [PATCH 12/13] Implement feature --- src/BitMono.CLI/BitMono.CLI.csproj | 1 + src/BitMono.CLI/GlobalUsings.cs | 2 + .../Modules/CLIObfuscationNeedsFactory.cs | 3 +- src/BitMono.CLI/Modules/CLIOptions.cs | 15 ++++++ .../CLIOptionsObfuscationNeedsFactory.cs | 50 +++++++++++++++++++ src/BitMono.CLI/Program.cs | 12 ++++- .../IObfuscationNeedsFactory.cs | 2 +- 7 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 src/BitMono.CLI/Modules/CLIOptions.cs create mode 100644 src/BitMono.CLI/Modules/CLIOptionsObfuscationNeedsFactory.cs diff --git a/src/BitMono.CLI/BitMono.CLI.csproj b/src/BitMono.CLI/BitMono.CLI.csproj index c1998590..3b5c1d4e 100644 --- a/src/BitMono.CLI/BitMono.CLI.csproj +++ b/src/BitMono.CLI/BitMono.CLI.csproj @@ -9,6 +9,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/BitMono.CLI/GlobalUsings.cs b/src/BitMono.CLI/GlobalUsings.cs index 5f557f31..c18e37df 100644 --- a/src/BitMono.CLI/GlobalUsings.cs +++ b/src/BitMono.CLI/GlobalUsings.cs @@ -10,6 +10,7 @@ global using System; global using System.Collections.Generic; global using System.Diagnostics; +global using System.Diagnostics.CodeAnalysis; global using System.IO; global using System.Linq; global using System.Threading; @@ -17,6 +18,7 @@ global using BitMono.Core.Extensions; global using BitMono.Host.Extensions; global using BitMono.Shared.Models; +global using CommandLine; global using Microsoft.Extensions.Options; global using Pocket.Extensions; global using Serilog; diff --git a/src/BitMono.CLI/Modules/CLIObfuscationNeedsFactory.cs b/src/BitMono.CLI/Modules/CLIObfuscationNeedsFactory.cs index a4e7486b..670951e7 100644 --- a/src/BitMono.CLI/Modules/CLIObfuscationNeedsFactory.cs +++ b/src/BitMono.CLI/Modules/CLIObfuscationNeedsFactory.cs @@ -1,5 +1,6 @@ namespace BitMono.CLI.Modules; +[SuppressMessage("ReSharper", "InconsistentNaming")] public class CLIObfuscationNeedsFactory : IObfuscationNeedsFactory { private readonly string[] m_Args; @@ -87,9 +88,7 @@ public ObfuscationNeeds Create() return new ObfuscationNeeds { -#pragma warning disable CS8601 FileName = fileName, -#pragma warning restore CS8601 FileBaseDirectory = fileBaseDirectory, DependenciesDirectoryName = dependenciesDirectoryName, OutputDirectoryName = outputDirectoryName diff --git a/src/BitMono.CLI/Modules/CLIOptions.cs b/src/BitMono.CLI/Modules/CLIOptions.cs new file mode 100644 index 00000000..7739ec50 --- /dev/null +++ b/src/BitMono.CLI/Modules/CLIOptions.cs @@ -0,0 +1,15 @@ +namespace BitMono.CLI.Modules; + +[SuppressMessage("ReSharper", "InconsistentNaming")] +[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")] +public class CLIOptions +{ + [Option('f', "file", Required = true, HelpText = "Set file path.")] + public string? File { get; set; } + + [Option('l', "libraries", Required = false, HelpText = "Set libraries path.")] + public string? Libraries { get; set; } + + [Option('o', "output", Required = false, HelpText = "Set output path.")] + public string? Output { get; set; } +} \ No newline at end of file diff --git a/src/BitMono.CLI/Modules/CLIOptionsObfuscationNeedsFactory.cs b/src/BitMono.CLI/Modules/CLIOptionsObfuscationNeedsFactory.cs new file mode 100644 index 00000000..18348e17 --- /dev/null +++ b/src/BitMono.CLI/Modules/CLIOptionsObfuscationNeedsFactory.cs @@ -0,0 +1,50 @@ +#pragma warning disable CS8604 +namespace BitMono.CLI.Modules; + +[SuppressMessage("ReSharper", "InconsistentNaming")] +public class CLIOptionsObfuscationNeedsFactory : IObfuscationNeedsFactory +{ + private readonly string[] m_Args; + + public CLIOptionsObfuscationNeedsFactory(string[] args) + { + m_Args = args; + } + + [SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")] + public ObfuscationNeeds? Create() + { + var parser = new Parser(with => + { + with.EnableDashDash = true; + with.HelpWriter = Console.Error; + }); + var parserResult = parser.ParseArguments(m_Args); + if (parserResult.Errors.IsEmpty() == false) + { + return null; + } + var options = parserResult.Value; + if (File.Exists(options.File) == false) + { + Console.WriteLine("File cannot be found, please, try again!"); + return null; + } + var fileBaseDirectory = Path.GetDirectoryName(options.File); + var needs = new ObfuscationNeeds + { + FileName = options.File, + FileBaseDirectory = fileBaseDirectory, + DependenciesDirectoryName = options.Libraries.IsNullOrEmpty() == false + ? options.Libraries + : Path.Combine(fileBaseDirectory, "libs"), + OutputDirectoryName = options.Output.IsNullOrEmpty() == false + ? options.Output + : Path.Combine(fileBaseDirectory, "output") + }; + + Directory.CreateDirectory(needs.OutputDirectoryName); + Directory.CreateDirectory(needs.DependenciesDirectoryName); + return needs; + } +} \ No newline at end of file diff --git a/src/BitMono.CLI/Program.cs b/src/BitMono.CLI/Program.cs index 890424b0..163a5a04 100644 --- a/src/BitMono.CLI/Program.cs +++ b/src/BitMono.CLI/Program.cs @@ -7,11 +7,19 @@ private static async Task Main(string[] args) { try { - var needs = new CLIObfuscationNeedsFactory(args).Create(); + ObfuscationNeeds? needs = null; + needs = args.IsEmpty() + ? new CLIObfuscationNeedsFactory(args).Create() + : new CLIOptionsObfuscationNeedsFactory(args).Create(); + if (needs == null) + { + return; + } + Console.Clear(); Console.WriteLine("File: {0}", needs.FileName); Console.WriteLine("Dependencies (libs): {0}", needs.DependenciesDirectoryName); - Console.WriteLine("Everything is seems to be good, starting obfuscation.."); + Console.WriteLine("Everything is seems to be ok, starting obfuscation.."); var module = new BitMonoModule( configureContainer => configureContainer.AddProtections(), diff --git a/src/BitMono.Obfuscation.API/IObfuscationNeedsFactory.cs b/src/BitMono.Obfuscation.API/IObfuscationNeedsFactory.cs index 23b9b70c..afc25e33 100644 --- a/src/BitMono.Obfuscation.API/IObfuscationNeedsFactory.cs +++ b/src/BitMono.Obfuscation.API/IObfuscationNeedsFactory.cs @@ -2,5 +2,5 @@ public interface IObfuscationNeedsFactory { - ObfuscationNeeds Create(); + ObfuscationNeeds? Create(); } \ No newline at end of file From 00600dcb0cb440d585694ee702d9b572416220c9 Mon Sep 17 00:00:00 2001 From: sunnamed434 <65300126+sunnamed434@users.noreply.github.com> Date: Mon, 13 Feb 2023 10:21:22 +0200 Subject: [PATCH 13/13] Update changelog and props --- CHANGELOG.md | 6 ++++++ props/SharedProjectProps.props | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4eb587f..333967bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ | Versions: | | - | +| [v0.10.0-alpha](#v0100-alpha19) | | [v0.9.0-alpha](#v090-alpha18) | | [v0.8.0-alpha](#v080-alpha17) | | [v0.7.0-alpha](#v070-alpha16) | @@ -20,6 +21,11 @@ | [v0.1.0](#v010) | --- +### v0.10.0-alpha.19: +2023-02-013 +#### Added: +* Command line arguments [#82](https://github.com/sunnamed434/BitMono/issues/82) + ### v0.9.0-alpha.18: 2023-02-09 #### Changed: diff --git a/props/SharedProjectProps.props b/props/SharedProjectProps.props index 18507f05..ae8f223f 100644 --- a/props/SharedProjectProps.props +++ b/props/SharedProjectProps.props @@ -6,12 +6,12 @@ MIT https://github.com/sunnamed434/BitMono sunnamed434 - 0.9.0-alpha.18 + 0.10.0-alpha.19 https://github.com/sunnamed434/BitMono git sunnamed434 - 0.9.0-alpha.18 - 0.9.0-alpha.18 + 0.10.0-alpha.19 + 0.10.0-alpha.19 BitMono sunnamed434 10