Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix obfuscation attributes strip #194

Merged
merged 1 commit into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/BitMono.API/Resolvers/IAttributeResolver.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
namespace BitMono.API.Resolvers;

public interface IAttributeResolver<TModel>
where TModel : class
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
public interface IAttributeResolver<TModel> where TModel : class
{
bool Resolve(string? featureName, IHasCustomAttribute from, out TModel? model);
bool Resolve(string? featureName, IHasCustomAttribute from, [NotNullWhen(true)] out TModel? model);
bool Resolve(string? featureName, IHasCustomAttribute from);
bool Resolve(IHasCustomAttribute from);
bool Resolve(Type featureType, IHasCustomAttribute from);
Expand Down
1 change: 1 addition & 0 deletions src/BitMono.API/Resolvers/IMemberResolver.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace BitMono.API.Resolvers;

[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
public interface IMemberResolver
{
bool Resolve(IProtection protection, IMetadataMember member);
Expand Down
18 changes: 10 additions & 8 deletions src/BitMono.CLI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ internal class Program
private static CancellationToken CancellationToken => CancellationTokenSource.Token;
private static readonly string BitMonoFileVersionText =
$"BitMono v{FileVersionInfo.GetVersionInfo(typeof(Program).Assembly.Location).FileVersion}";
private static readonly string AsciiArt = @$"
___ _ __ __ ___
/ _ )(_) /_/ |/ /__ ___ ___
/ _ / / __/ /|_/ / _ \/ _ \/ _ \
/____/_/\__/_/ /_/\___/_//_/\___/
https://github.com/sunnamed434/BitMono
{BitMonoFileVersionText}";
private static readonly string AsciiArt = $"""

___ _ __ __ ___
/ _ )(_) /_/ |/ /__ ___ ___
/ _ / / __/ /|_/ / _ \/ _ \/ _ \
/____/_/\__/_/ /_/\___/_//_/\___/
https://github.com/sunnamed434/BitMono
{BitMonoFileVersionText}
""";

private static async Task<int> Main(string[] args)
{
Expand Down Expand Up @@ -53,7 +55,7 @@ private static async Task<int> Main(string[] args)

var info = new IncompleteFileInfo(needs.FileName, needs.ReferencesDirectoryName, needs.OutputPath);
var engine = new BitMonoStarter(serviceProvider);
var succeed = await engine.StartAsync(info, CancellationTokenSource.Token);
var succeed = await engine.StartAsync(info, CancellationToken);
if (succeed == false)
{
logger.Fatal("Engine has fatal issues, unable to continue!");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace BitMono.Core.Analyzing;

[UsedImplicitly]
public class CriticalMethodsCriticalAnalyzer : ICriticalAnalyzer<MethodDefinition>
{
private readonly CriticalsSettings _criticalsSettings;
Expand Down
1 change: 0 additions & 1 deletion src/BitMono.Core/Contexts/StarterContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace BitMono.Core.Contexts;

[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
public class StarterContext
{
#pragma warning disable CS8618
Expand Down
2 changes: 1 addition & 1 deletion src/BitMono.Core/Extensions/KeyValuePairsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static bool GetValueOrDefault(this Dictionary<string, object> source, str
}
return value;
}
public static bool TryGetTypedValue<TKey, TValue, TActual>(this IDictionary<TKey, TValue> source, TKey key, out TActual? value)
public static bool TryGetTypedValue<TKey, TValue, TActual>(this IDictionary<TKey, TValue> source, TKey key, [NotNullWhen(true)] out TActual? value)
where TActual : TValue
{
if (source.TryGetValue(key, out var tempValue))
Expand Down
3 changes: 2 additions & 1 deletion src/BitMono.Core/Resolvers/AttemptAttributeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

public static class AttemptAttributeResolver
{
public static bool TryResolve(IHasCustomAttribute from, string @namespace, string name, out List<CustomAttributeResolve>? attributesResolve)
public static bool TryResolve(IHasCustomAttribute from, string @namespace, string name,
[NotNullWhen(true)] out List<CustomAttributeResolve>? attributesResolve)
{
attributesResolve = CustomAttributeResolver.Resolve(from, @namespace, name);
return attributesResolve.IsNullOrEmpty() == false;
Expand Down
2 changes: 1 addition & 1 deletion src/BitMono.Core/Resolvers/AttributeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class AttributeResolver<TModel> : IAttributeResolver<TModel> where TModel : class
{
public virtual bool Resolve(string? featureName, IHasCustomAttribute from, out TModel? model)
public virtual bool Resolve(string? featureName, IHasCustomAttribute from, [NotNullWhen(true)] out TModel? model)
{
model = default;
return false;
Expand Down
17 changes: 7 additions & 10 deletions src/BitMono.Core/Resolvers/CriticalAttributeResolver.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
namespace BitMono.Core.Resolvers;

[UsedImplicitly]
[SuppressMessage("ReSharper", "InvertIf")]
[SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")]
public class CriticalAttributeResolver : AttributeResolver<CustomAttributeResolve>
{
private readonly CriticalsSettings _criticalsSettings;
Expand All @@ -13,7 +10,7 @@ public CriticalAttributeResolver(IOptions<CriticalsSettings> criticals)
}

public override bool Resolve(string? feature, IHasCustomAttribute from,
out CustomAttributeResolve? attributeResolve)
[NotNullWhen(true)] out CustomAttributeResolve? attributeResolve)
{
attributeResolve = null;
if (_criticalsSettings.UseCriticalAttributes == false)
Expand All @@ -22,17 +19,17 @@ public override bool Resolve(string? feature, IHasCustomAttribute from,
}

var criticalAttributes = _criticalsSettings.CriticalAttributes;
for (var i = 0; i < criticalAttributes.Count; i++)
foreach (var criticalAttribute in criticalAttributes)
{
var criticalAttribute = criticalAttributes[i];
if (AttemptAttributeResolver.TryResolve(from, criticalAttribute.Namespace, criticalAttribute.Name,
out var attributesResolve))
out var attributesResolve) == false)
{
attributeResolve = attributesResolve!.First();
return true;
continue;
}
}

attributeResolve = attributesResolve.First();
return true;
}
return false;
}
}
2 changes: 0 additions & 2 deletions src/BitMono.Core/Resolvers/DoNotResolveMemberResolver.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
namespace BitMono.Core.Resolvers;

[UsedImplicitly]
[SuppressMessage("ReSharper", "InvertIf")]
public class DoNotResolveMemberResolver : IMemberResolver
{
private readonly RuntimeCriticalAnalyzer _runtimeCriticalAnalyzer;
Expand Down
2 changes: 0 additions & 2 deletions src/BitMono.Core/Resolvers/NoInliningMethodMemberResolver.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
namespace BitMono.Core.Resolvers;

[SuppressMessage("ReSharper", "InvertIf")]
[SuppressMessage("ReSharper", "MergeIntoPattern")]
public class NoInliningMethodMemberResolver : IMemberResolver
{
private readonly ObfuscationSettings _obfuscationSettings;
Expand Down
23 changes: 18 additions & 5 deletions src/BitMono.Core/Resolvers/ObfuscateAssemblyAttributeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ public class ObfuscateAssemblyAttributeResolver : AttributeResolver<ObfuscateAss
public ObfuscateAssemblyAttributeResolver(IOptions<ObfuscationSettings> configuration)
{
_obfuscationSettings = configuration.Value;
_attributeNamespace = typeof(ObfuscateAssemblyAttribute).Namespace;
_attributeNamespace = typeof(ObfuscateAssemblyAttribute).Namespace!;
_attributeName = nameof(ObfuscateAssemblyAttribute);
}

public override bool Resolve(string? feature, IHasCustomAttribute from, out ObfuscateAssemblyAttributeData? model)
public override bool Resolve(string? feature, IHasCustomAttribute from, [NotNullWhen(true)] out ObfuscateAssemblyAttributeData? model)
{
model = null;
if (_obfuscationSettings.ObfuscateAssemblyAttributeObfuscationExclude == false)
Expand All @@ -25,11 +25,24 @@ public override bool Resolve(string? feature, IHasCustomAttribute from, out Obfu
{
return false;
}
var attribute = attributesResolve.First();
var namedValues = attribute.NamedValues;
if (namedValues == null)
{
return false;
}
var fixedValues = attribute.FixedValues;
if (fixedValues == null || fixedValues.Count == 0)
{
return false;
}
if (fixedValues.ElementAtOrDefault(0) is not bool assemblyIsPrivate)
{
return false;
}

var attribute = attributesResolve!.First();
var assemblyIsPrivate = attribute.FixedValues![0] is bool;
var stripAfterObfuscation =
attribute.NamedValues!.GetValueOrDefault(nameof(ObfuscateAssemblyAttribute.StripAfterObfuscation),
namedValues.GetValueOrDefault(nameof(ObfuscateAssemblyAttribute.StripAfterObfuscation),
defaultValue: true);
model = new ObfuscateAssemblyAttributeData(assemblyIsPrivate, stripAfterObfuscation, attribute.Attribute);
return true;
Expand Down
70 changes: 37 additions & 33 deletions src/BitMono.Core/Resolvers/ObfuscationAttributeResolver.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
namespace BitMono.Core.Resolvers;

[SuppressMessage("ReSharper", "InvertIf")]
[SuppressMessage("ReSharper", "ForCanBeConvertedToForeach")]
public class ObfuscationAttributeResolver : AttributeResolver<ObfuscationAttributeData>
public class ObfuscationAttributeResolver : AttributeResolver<IReadOnlyList<ObfuscationAttributeData>>
{
private readonly ObfuscationSettings _obfuscationSettings;
private readonly string _attributeNamespace;
Expand All @@ -11,11 +9,11 @@ public class ObfuscationAttributeResolver : AttributeResolver<ObfuscationAttribu
public ObfuscationAttributeResolver(IOptions<ObfuscationSettings> configuration)
{
_obfuscationSettings = configuration.Value;
_attributeNamespace = typeof(ObfuscationAttribute).Namespace;
_attributeNamespace = typeof(ObfuscationAttribute).Namespace!;
_attributeName = nameof(ObfuscationAttribute);
}

public override bool Resolve(string? featureName, IHasCustomAttribute from, out ObfuscationAttributeData? model)
public override bool Resolve(string? featureName, IHasCustomAttribute from, [NotNullWhen(true)] out IReadOnlyList<ObfuscationAttributeData>? model)
{
model = null;
if (_obfuscationSettings.ObfuscationAttributeObfuscationExclude == false)
Expand All @@ -28,37 +26,43 @@ public override bool Resolve(string? featureName, IHasCustomAttribute from, out
return false;
}

for (var i = 0; i < attributesResolve!.Count; i++)
var attributes = new List<ObfuscationAttributeData>();
foreach (var attribute in attributesResolve)
{
var attribute = attributesResolve[i];
if (attribute.NamedValues?.TryGetTypedValue(nameof(ObfuscationAttribute.Feature), out string? feature) == true)
var namedValues = attribute.NamedValues;
if (namedValues == null)
{
if (feature!.Equals(featureName, StringComparison.OrdinalIgnoreCase))
{
var exclude =
attribute.NamedValues.GetValueOrDefault(nameof(ObfuscationAttribute.Exclude),
defaultValue: true);
var applyToMembers =
attribute.NamedValues.GetValueOrDefault(nameof(ObfuscationAttribute.Exclude),
defaultValue: true);
var stripAfterObfuscation =
attribute.NamedValues.GetValueOrDefault(nameof(ObfuscationAttribute.StripAfterObfuscation),
defaultValue: true);
if (exclude)
{
model = new ObfuscationAttributeData
{
Exclude = exclude,
ApplyToMembers = applyToMembers,
StripAfterObfuscation = stripAfterObfuscation,
Feature = feature,
CustomAttribute = attribute.Attribute
};
return true;
}
}
continue;
}
if (namedValues.TryGetTypedValue(nameof(ObfuscationAttribute.Feature), out string? feature) == false)
{
continue;
}
if (feature.Equals(featureName, StringComparison.OrdinalIgnoreCase) == false)
{
continue;
}

var exclude =
namedValues.GetValueOrDefault(nameof(ObfuscationAttribute.Exclude),
defaultValue: true);
var applyToMembers =
namedValues.GetValueOrDefault(nameof(ObfuscationAttribute.Exclude),
defaultValue: true);
var stripAfterObfuscation =
namedValues.GetValueOrDefault(nameof(ObfuscationAttribute.StripAfterObfuscation),
defaultValue: true);

attributes.Add(new ObfuscationAttributeData
{
Exclude = exclude,
ApplyToMembers = applyToMembers,
StripAfterObfuscation = stripAfterObfuscation,
Feature = feature,
CustomAttribute = attribute.Attribute
});
}
return false;
model = attributes;
return true;
}
}
18 changes: 6 additions & 12 deletions src/BitMono.Core/Resolvers/SafeToMakeChangesMemberResolver.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
namespace BitMono.Core.Resolvers;

[UsedImplicitly]
[SuppressMessage("ReSharper", "ConvertIfStatementToReturnStatement")]
public class SafeToMakeChangesMemberResolver : IMemberResolver
{
private readonly ObfuscationAttributeResolver _obfuscationAttributeResolver;
Expand Down Expand Up @@ -29,19 +27,15 @@ public bool Resolve(IProtection protection, IMetadataMember member)
if (member is IHasCustomAttribute customAttribute)
{
var feature = protection.GetName();
if (_obfuscationAttributeResolver.Resolve(feature, customAttribute, out var obfuscationAttributeData))
if (_obfuscationAttributeResolver.Resolve(feature, customAttribute, out var obfuscationAttributes)
&& obfuscationAttributes.Any(x => x.Exclude))
{
if (obfuscationAttributeData!.Exclude)
{
return false;
}
return false;
}
if (_obfuscateAssemblyAttributeResolver.Resolve(null, customAttribute, out var obfuscateAssemblyAttributeData))
if (_obfuscateAssemblyAttributeResolver.Resolve(null, customAttribute, out var obfuscateAssemblyAttributeData)
&& obfuscateAssemblyAttributeData!.AssemblyIsPrivate)
{
if (obfuscateAssemblyAttributeData!.AssemblyIsPrivate)
{
return false;
}
return false;
}
if (_criticalAttributeResolver.Resolve(feature, customAttribute))
{
Expand Down
2 changes: 1 addition & 1 deletion src/BitMono.Host/protections.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"Protections": [
{
"Name": "AntiILdasm",
"Enabled": true
"Enabled": false
},
{
"Name": "AntiDe4dot",
Expand Down
6 changes: 2 additions & 4 deletions src/BitMono.Obfuscation/BitMonoObfuscator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,16 +232,14 @@ private bool OptimizeMacros()
}
return true;
}
private bool StripObfuscationAttributes()
private void StripObfuscationAttributes()
{
if (_obfuscationSettings.StripObfuscationAttributes == false)
{
_logger.Information("Obfuscation attributes stripping is disabled (it's ok)");
return true;
return;
}
var obfuscationAttributesStrip = _obfuscationAttributesStripper.Strip(_context, _protectionsSort!);
_obfuscationAttributesStripNotifier.Notify(obfuscationAttributesStrip);
return true;
}
private bool CreatePEImage()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ public void Notify(ObfuscationAttributesStrip obfuscationAttributesStrip)
{
if (obfuscationAttributesStrip.ObfuscationAttributesSuccessStrip.IsEmpty() == false)
{
_logger.Information("Successfully stripped {0} obfuscation attribute(s)!",
_logger.Information("Successfully stripped {0} obfuscation attribute(s)",
obfuscationAttributesStrip.ObfuscationAttributesSuccessStrip.Count);
}
if (obfuscationAttributesStrip.ObfuscateAssemblyAttributesSuccessStrip.IsEmpty() == false)
{
_logger.Information("Successfully stripped {0} assembly obfuscation attribute(s)!",
_logger.Information("Successfully stripped {0} assembly obfuscation attribute(s)",
obfuscationAttributesStrip.ObfuscateAssemblyAttributesSuccessStrip.Count);
}
if (obfuscationAttributesStrip.ObfuscationAttributesFailStrip.IsEmpty() == false)
{
_logger.Information("Failed to strip {0} assembly obfuscation attribute(s)!",
_logger.Information("Failed to strip {0} assembly obfuscation attribute(s)",
obfuscationAttributesStrip.ObfuscationAttributesFailStrip.Count);
}
if (obfuscationAttributesStrip.ObfuscateAssemblyAttributesFailStrip.IsEmpty() == false)
{
_logger.Information("Failed to strip {0} obfuscation attribute(s)!",
_logger.Information("Failed to strip {0} obfuscation attribute(s)",
obfuscationAttributesStrip.ObfuscateAssemblyAttributesFailStrip.Count);
}
}
Expand Down
Loading
Loading