Closed 613038475 closed 9 years ago
Sorry, but no. ObfuscationAttribute has different semantics with the internal marking process. It would also make the Marker code complicated in order to support them.
I see one very good reason to support this attribute: when refactoring the code (renaming, moving clases/members), it won't require to update the configuration file.
Could you explain why "ObfuscationAttribute has different semantics with the internal marking process" ?
Here is the code I've implemented to add support for this attribute (in Marker.cs
):
protected void ApplyRules(ConfuserContext context, IDnlibDef target, Rules rules)
{
var ret = CheckObfuscationAttribute(context, target, rules);
foreach (var i in rules)
{
if (!(bool)i.Value.Evaluate(target)) continue;
if (!i.Key.Inherit)
ret.Clear();
FillPreset(i.Key.Preset, ret);
foreach (SettingItem<Protection> prot in i.Key)
{
if (prot.Action == SettingItemAction.Add)
ret[protections[prot.Id]] = new Dictionary<string, string>(prot, StringComparer.OrdinalIgnoreCase);
else
ret.Remove(protections[prot.Id]);
}
}
ProtectionParameters.SetParameters(context, target, ret);
}
private ProtectionSettings CheckObfuscationAttribute(ConfuserContext context, IDnlibDef target, Rules rules)
{
var result = new ProtectionSettings();
var parents = GetParents(target);
List<CustomAttribute> obfuscationAttributes = new List<CustomAttribute>();
obfuscationAttributes.AddRange(from parent in parents
from customAttribute in parent.CustomAttributes
where customAttribute.TypeFullName == "System.Reflection.ObfuscationAttribute"
let property = customAttribute.GetProperty("ApplyToMembers")
where property != null ? (bool)property.Value : true
select customAttribute);
obfuscationAttributes.AddRange(from customAttribute in target.CustomAttributes
where customAttribute.TypeFullName == "System.Reflection.ObfuscationAttribute"
select customAttribute);
if (obfuscationAttributes.Count == 0)
return result;
foreach (CustomAttribute obfuscationAttribute in obfuscationAttributes)
{
var property = obfuscationAttribute.GetProperty("Exclude");
bool exclude = property != null ? (bool)property.Value : true;
property = obfuscationAttribute.GetProperty("Feature");
string feature = property != null ? ((UTF8String)property.Value).String : "all";
if (feature == "all")
{
if (exclude)
result.Clear();
else
foreach (var value in protections.Values)
result[value] = new Dictionary<string, string>(new Dictionary<string, string>(), StringComparer.OrdinalIgnoreCase);
}
else
{
if (exclude)
result.Remove(protections[feature]);
else
result[protections[feature]] = new Dictionary<string, string>(new Dictionary<string, string>(), StringComparer.OrdinalIgnoreCase);
}
}
return result;
}
private static IEnumerable<IDnlibDef> GetParents(IDnlibDef target)
{
List<IDnlibDef> result = new List<IDnlibDef>();
do
{
target = GetParent(target);
if (target == null)
break;
result.Add(target);
} while (true);
result.Reverse();
return result;
}
private static IDnlibDef GetParent(IDnlibDef target)
{
if (target is AssemblyDef)
return null;
if (target is ModuleDef)
return ((ModuleDef)target).Assembly;
IMemberDef memberDef = target as IMemberDef;
if (memberDef != null)
{
TypeDef result = memberDef.DeclaringType;
if (result != null)
return result;
if (target is TypeDef)
return ((TypeDef)target).Module;
}
throw new InvalidOperationException("AFAIK This shouldn't happen.");
}
That's one good use of ObfuscationAttribute. I'll consider supporting this feature.
By 'different semantics', the way ObfuscationAttribute works is inconsistent with ConfuserEx's rule system. Take 'Exclude' property as an example, does it means 'Exclude the whole item from protection' or 'exclude the rules in this attribute from the item'? The documentation of this attribute is ambiguous about its exact semantic and how should we interpret the attribute.
Also, it's hard to describe the rich options of ConfuserEx --- all it provides is a single Features field. Users can use the current UI to specify a protection preset, add/remove protections, and specify protection parameters. To support these options, some kind of format would have to be used.
@yck1509 Is it possible to implement ConfuserEx pattern that allows to match attributes, so that ObfuscationAttribute in question would be just a particular case? Then ConfuserEx rich options are preserved and supporting obfuscation of attributed code is possible.
I have a case when I have partially-obfuscated third-party library heavily marked with ObfuscationAttribute and license requirement that I should obfuscate the rest before shipping my own product. So I'd like to run ConfuserEx on it and have it protect everything not excluded by the attribute.
Or maybe I missed something already existing?
@yck1509 Please add ObfuscationAttribute scheme for Include and Exclude, currently rules scheme is really hard to use.
Very happy to see public members rename support added, Can also add support for ObfuscationAttribute? Here is the description page: http://msdn.microsoft.com/en-us/library/system.reflection.obfuscationattribute%28v=vs.110%29.aspx