Skip to content

Commit b515dd0

Browse files
committed
Fix #224 and make it so user can input --protections right in the args
1 parent 797859b commit b515dd0

12 files changed

Lines changed: 149 additions & 17 deletions

src/BitMono.CLI/GlobalUsings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@
1919
global using Microsoft.Extensions.Options;
2020
global using Pocket.Extensions;
2121
global using Serilog;
22+
global using System.Collections.Generic;
23+
global using System.Linq;
2224
global using Serilog.Configuration;
2325
global using ILogger = Serilog.ILogger;

src/BitMono.CLI/Modules/ObfuscationNeeds.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ internal class ObfuscationNeeds
88
public string ReferencesDirectoryName { get; set; }
99
public string OutputPath { get; set; }
1010
public ObfuscationNeedsWay Way { get; set; }
11+
public List<string> Protections { get; set; }
1112
#pragma warning restore CS8618
1213
}
1314

src/BitMono.CLI/Modules/ObfuscationNeedsFactory.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,22 @@ internal class ObfuscationNeedsFactory
44
{
55
private readonly string[] _args;
66
private readonly ObfuscationSettings _obfuscationSettings;
7+
private readonly List<ProtectionSetting> _protectionSettings;
78
private readonly ILogger _logger;
89

910
public ObfuscationNeedsFactory(string[] args,
10-
ObfuscationSettings obfuscationSettings, ILogger logger)
11+
ObfuscationSettings obfuscationSettings, List<ProtectionSetting> protectionSettings, ILogger logger)
1112
{
1213
_args = args;
1314
_obfuscationSettings = obfuscationSettings;
15+
_protectionSettings = protectionSettings;
1416
_logger = logger;
1517
}
1618

1719
public ObfuscationNeeds? Create(CancellationToken cancellationToken)
1820
{
1921
return _args.IsEmpty()
20-
? new ReadlineObfuscationNeedsFactory(_args, _obfuscationSettings, _logger).Create(cancellationToken)
22+
? new ReadlineObfuscationNeedsFactory(_args, _obfuscationSettings, _protectionSettings, _logger).Create(cancellationToken)
2123
: new OptionsObfuscationNeedsFactory(_args, _obfuscationSettings, _logger).Create(cancellationToken);
2224
}
2325
}

src/BitMono.CLI/Modules/Options.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ internal class Options
1010

1111
[Option('o', "output", Required = false, HelpText = "Set output path.")]
1212
public string? Output { get; set; }
13+
14+
[Option('p', "protections", Required = false, HelpText = "Set protections, also can be set via protections.json.")]
15+
public IEnumerable<string> Protections { get; set; } = [];
1316
}

src/BitMono.CLI/Modules/OptionsObfuscationNeedsFactory.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ internal class OptionsObfuscationNeedsFactory
66
private readonly ObfuscationSettings _obfuscationSettings;
77
private readonly ILogger _logger;
88

9-
public OptionsObfuscationNeedsFactory(string[] args,
10-
ObfuscationSettings obfuscationSettings, ILogger logger)
9+
public OptionsObfuscationNeedsFactory(string[] args, ObfuscationSettings obfuscationSettings, ILogger logger)
1110
{
1211
_args = args;
1312
_obfuscationSettings = obfuscationSettings;
@@ -44,6 +43,7 @@ public OptionsObfuscationNeedsFactory(string[] args,
4443
FileBaseDirectory = fileBaseDirectory,
4544
ReferencesDirectoryName = fileBaseDirectory,
4645
OutputPath = fileBaseDirectory,
46+
Protections = options.Protections.ToList(),
4747
Way = ObfuscationNeedsWay.Options
4848
};
4949
}
@@ -59,6 +59,7 @@ public OptionsObfuscationNeedsFactory(string[] args,
5959
OutputPath = options.Output?.IsNullOrEmpty() == false
6060
? options.Output
6161
: Path.Combine(fileBaseDirectory, _obfuscationSettings.OutputDirectoryName),
62+
Protections = options.Protections.ToList(),
6263
Way = ObfuscationNeedsWay.Options
6364
};
6465
}

src/BitMono.CLI/Modules/ReadlineObfuscationNeedsFactory.cs

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ internal class ReadlineObfuscationNeedsFactory
44
{
55
private readonly string[] _args;
66
private readonly ObfuscationSettings _obfuscationSettings;
7+
private readonly List<ProtectionSetting> _protectionSettings;
78
private readonly ILogger _logger;
89

9-
public ReadlineObfuscationNeedsFactory(string[] args, ObfuscationSettings obfuscationSettings, ILogger logger)
10+
public ReadlineObfuscationNeedsFactory(string[] args, ObfuscationSettings obfuscationSettings,
11+
List<ProtectionSetting> protectionSettings, ILogger logger)
1012
{
1113
_args = args;
1214
_obfuscationSettings = obfuscationSettings;
15+
_protectionSettings = protectionSettings;
1316
_logger = logger.ForContext<ReadlineObfuscationNeedsFactory>();
1417
}
1518

@@ -52,6 +55,96 @@ public ObfuscationNeeds Create(CancellationToken cancellationToken)
5255
}
5356
}
5457

58+
List<string> protections = [];
59+
60+
bool hasEnabledProtections = _protectionSettings != null && _protectionSettings.Any(x => x.Enabled);
61+
bool hasAnyProtectionSettings = _protectionSettings != null && _protectionSettings.Any();
62+
63+
if (!hasEnabledProtections)
64+
{
65+
if (!hasAnyProtectionSettings)
66+
{
67+
_logger.Warning("No protection settings found (protections.json may be missing or empty)");
68+
_logger.Information("Please input the preferred protections with ',' delimiter, example: StringsEncryption,AntiDe4dot,ControlFlow");
69+
}
70+
else
71+
{
72+
_logger.Warning("No protection is enabled in protections.json file, please either enable any protection first or input the preferred with ',' delimiter, example: StringsEncryption,AntiDe4dot");
73+
}
74+
75+
while (true)
76+
{
77+
try
78+
{
79+
cancellationToken.ThrowIfCancellationRequested();
80+
81+
var protectionInput = Console.ReadLine();
82+
cancellationToken.ThrowIfCancellationRequested();
83+
84+
if (!string.IsNullOrWhiteSpace(protectionInput))
85+
{
86+
var inputProtections = protectionInput.Split([','], StringSplitOptions.RemoveEmptyEntries)
87+
.Select(p => p.Trim())
88+
.Where(p => !string.IsNullOrWhiteSpace(p))
89+
.ToList();
90+
91+
if (inputProtections.Any())
92+
{
93+
// If we have protection settings, validate against them but allow unknown protections
94+
if (hasAnyProtectionSettings)
95+
{
96+
var availableProtections = _protectionSettings.Select(p => p.Name).ToList();
97+
var unknownProtections = inputProtections.Where(p => !availableProtections.Contains(p, StringComparer.OrdinalIgnoreCase)).ToList();
98+
99+
if (unknownProtections.Any())
100+
{
101+
_logger.Warning("The following protection(s) are not found in current protections.json but will be used anyway: {0}",
102+
string.Join(", ", unknownProtections));
103+
_logger.Information("Available protections in config: {0}",
104+
availableProtections.Any() ? string.Join(", ", availableProtections) : "none");
105+
}
106+
107+
var knownProtections = inputProtections.Where(p => availableProtections.Contains(p, StringComparer.OrdinalIgnoreCase)).ToList();
108+
if (knownProtections.Any())
109+
{
110+
_logger.Information("Recognized protection(s) from config: {0}", string.Join(", ", knownProtections));
111+
}
112+
}
113+
else
114+
{
115+
_logger.Warning("Cannot validate protection names as protections.json is missing/empty. Using specified protections as-is.");
116+
}
117+
118+
protections = inputProtections;
119+
_logger.Information("Protections successfully specified: {0}", string.Join(", ", protections));
120+
break;
121+
}
122+
123+
_logger.Warning("No valid protections found in input, please try again!");
124+
}
125+
else
126+
{
127+
_logger.Information("No protections specified, continuing without additional protections...");
128+
break;
129+
}
130+
}
131+
catch (OperationCanceledException)
132+
{
133+
throw;
134+
}
135+
catch (Exception ex)
136+
{
137+
_logger.Error(ex, "Something went wrong while specifying protections");
138+
}
139+
}
140+
}
141+
else
142+
{
143+
// Use enabled protections from settings
144+
protections = _protectionSettings.Where(x => x.Enabled).Select(x => x.Name).ToList();
145+
_logger.Information("Using enabled protections from settings: {0}", string.Join(", ", protections));
146+
}
147+
55148
string dependenciesDirectoryName;
56149
string outputDirectoryName;
57150
var fileBaseDirectory = Path.GetDirectoryName(fileName);
@@ -112,7 +205,7 @@ public ObfuscationNeeds Create(CancellationToken cancellationToken)
112205
}
113206
else
114207
{
115-
_logger.Information("Dependencies (libs) directory was automatically found in: {0}!",
208+
_logger.Information("Dependencies (libs) directory was automatically found in: {0}",
116209
dependenciesDirectoryName);
117210
}
118211
}
@@ -125,7 +218,8 @@ public ObfuscationNeeds Create(CancellationToken cancellationToken)
125218
FileBaseDirectory = fileBaseDirectory,
126219
ReferencesDirectoryName = dependenciesDirectoryName,
127220
OutputPath = outputDirectoryName,
128-
Way = ObfuscationNeedsWay.Readline
221+
Way = ObfuscationNeedsWay.Readline,
222+
Protections = protections,
129223
};
130224
}
131225

src/BitMono.CLI/Program.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,24 @@ private static async Task<int> Main(string[] args)
3636
var logger = serviceProvider
3737
.GetRequiredService<ILogger>()
3838
.ForContext<Program>();
39-
needs = new ObfuscationNeedsFactory(args, obfuscation, logger).Create(CancellationToken);
39+
var protections = serviceProvider.GetRequiredService<IOptions<ProtectionSettings>>().Value.Protections!;
40+
needs = new ObfuscationNeedsFactory(args, obfuscation, protections, logger).Create(CancellationToken);
4041
if (needs == null)
4142
{
4243
statusCode = KnownReturnStatuses.Failure;
4344
return statusCode;
4445
}
4546

47+
if (needs.Protections.Count != 0)
48+
{
49+
protections.Clear();
50+
protections.AddRange(needs.Protections.Select(x => new ProtectionSetting
51+
{
52+
Enabled = true,
53+
Name = x
54+
}).ToList());
55+
}
56+
4657
CancellationToken.ThrowIfCancellationRequested();
4758

4859
if (obfuscation.ClearCLI)

src/BitMono.GlobalTool/.config/dotnet-tools.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/BitMono.GlobalTool/BitMono.GlobalTool.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@
1919
<Compile Include="..\BitMono.CLI\Modules\LoggerConfiguratorExtensions.cs">
2020
<Link>Modules\LoggerConfiguratorExtensions.cs</Link>
2121
</Compile>
22+
<Compile Include="..\BitMono.CLI\Modules\ObfuscationNeedsFactory.cs">
23+
<Link>Modules\ObfuscationNeedsFactory.cs</Link>
24+
</Compile>
2225
<Compile Include="..\BitMono.CLI\Modules\OptionsObfuscationNeedsFactory.cs">
2326
<Link>Modules\OptionsObfuscationNeedsFactory.cs</Link>
2427
</Compile>
28+
<Compile Include="..\BitMono.CLI\Modules\ReadlineObfuscationNeedsFactory.cs">
29+
<Link>Modules\ReadlineObfuscationNeedsFactory.cs</Link>
30+
</Compile>
2531
<Compile Include="..\BitMono.CLI\KnownReturnStatuses.cs">
2632
<Link>KnownReturnStatuses.cs</Link>
2733
</Compile>

src/BitMono.GlobalTool/GlobalUsings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
global using BitMono.Shared.Models;
1717
global using BitMono.Utilities.Paths;
1818
global using CommandLine;
19+
global using System.Linq;
1920
global using Microsoft.Extensions.DependencyInjection;
2021
global using Microsoft.Extensions.Options;
2122
global using Pocket.Extensions;
2223
global using Serilog;
24+
global using System.Collections.Generic;
2325
global using Serilog.Configuration;
2426
global using ILogger = Serilog.ILogger;

0 commit comments

Comments
 (0)