SmartAssembly does not seem to obfuscate internal property in an internal class
sol_smart
Posts: 8 New member
Hi,
We're evaluating SmartAssembly. Until now everything works perfectly - except for one scenario:
The tool doesn't seem to obfuscate internal properties in an internal class in a c# class library.
I've attached a sample solution with a sample saproj file. SmartAssembly correctly obfuscates class and method names. However, the internal properties are just left with their original name.
Could you please clarify - or point me in a direction on how to solve this.
Many thanks!
- sol
We're evaluating SmartAssembly. Until now everything works perfectly - except for one scenario:
The tool doesn't seem to obfuscate internal properties in an internal class in a c# class library.
I've attached a sample solution with a sample saproj file. SmartAssembly correctly obfuscates class and method names. However, the internal properties are just left with their original name.
Could you please clarify - or point me in a direction on how to solve this.
Many thanks!
- sol
Tagged:
Answers
Also, another question: We have some scenarios where an internal interface is also not renamed during obfuscation. I was not able to reproduce it outside our application. But I was wondering why the ForceObfuscate is not applicable to interfaces? (it can only be applied to classes, methods, structs, properties, and fields).
However, I find it a bit counterintuitive that pruning both removes unused code and also renames properties? Shouldn't renaming properties be the job of the 'name obfuscate' settings?
We use dependency injection heavily in our application, and since we're registering interfaces and classes by convention, it means that we have a lot "unused" classes (because only their interfaces are referenced). Enabling pruning removes all of those classes (which results in runtime errors), but it fixes the issue with property name obfuscation... in the end we're just stuck with a similar problem where we have to throw around DoNotPrune attributes to all of our classes, which is just as infeasible as writing ForceObfuscate to all of our properties.
I look forward to hearing from you.
- sol
Jessica Ramos | Product Support Engineer | Redgate Software
Have you visited our Help Center?
Thanks for your quick reply. I think to sum up on my three previous posts (and sorry for just posting away), what we're really missing, and I think would greatly improve your product, are theese improvements - in order of importance to us:
1. The ability to only obfuscate (i.e. specifically just rename) properties and events (even though it may technically be 'pruning'). In these days where Dependency Injection is increasingly popular, the concept of 'pruning' is simply too risky to enable, because so many classes and constructors are seen as unused through the eyes of static analysis. What we would love is the ability to just have properties and events renamed - SmartAssembly shouldn't remove anything that it deems "unused". I know we get that flexibility through annotations, but it is simply too big a task to apply those attributes manually. Perhaps it could be an entirely new option? Perhaps it could be a sub-option/switch for pruning?
2. The ability to apply the 'ForceObfuscate' attribute to interfaces (the use case is 'internal interfaces').
3. The ability to tell SmartAssembly to treat obfuscation attributes (ForceObfuscate, etc.) as inherited. It would be great to just be able to apply these attributes to a base class and then have them flow down a type inheritance hierarchy.
4. The ability to do Cross Assembly Renaming. I know this is probably not a small feat, and I know that someone has previously asked you about this on the forum. So perhaps you could just follow up on a status on this?
All of the above could of course easily be opt-in settings, such that you don't disturb existing setups.
Again, many many thanks for creating an awesome easy-to-use product. We've evaluated severaly obfuscators and I definitely think that yours is best value-for-money!
I look forward to hearing from you!
- sol
1. The ability to only rename (we assume this can only be by pruning) just properties and event names. (Added feature request SA-2222)
2. The ability to apply the 'ForceObfuscate' attribute to interfaces (the use case is 'internal interfaces').
- This is a bug (SA-2223), but it is easy to fix so expect it to be fixed in the next release (or a near release, depending on our schedule).
- As a temporary workaround, you can add the code below into you application:
and use it instead of the current
ForceObfuscateAttribute
definition.3. The ability to tell SmartAssembly to treat obfuscation attributes (ForceObfuscate, etc.) as inherited.
- This has been requested before (logged as SA-2082).
We are still not convinced that it is a good idea to allow users to do something like this given the problems that can arise from obfuscating derived classes but not the base class, or a combination thereof. Still, it remains on the planning list but we haven't decided what to do with it.
4. The ability to do Cross Assembly Renaming.
- This has been requested before (SA-1438) so I've added this to the issue and it will be brought up in planning.
Many many many thanks for your detailed response! Really appreciate it!
1. Just so we're on the same page regarding this feature request. What I would really love is the ability to have SmartAssembly easily rename properties & events into something incomprehensible. Today I can achieve that in two sub-optimal ways:
A) I can manually apply the [ForceObfuscate] attribute to a property/event (see below) and it works as intended. E.g. if a property was originally named 'MyInternalProperty' it will be renamed to something like '#xyz'. This is great but not feasible in a large solution.
B ) I can enable pruning, but that basically does a lot of other stuff which is indesirable, e.g. removing classes and constructors that through the eyes of static analysis is deemed unused, which basically destroys Dependency Injection with convention based registration (which I guess an increasing number of people use these days? ).
I basically just need SmartAssembly to have a third easy option to automatically only rename all properties & events into gibberish (without doing anything else - it should NOT remove any properties, classes, constructors or anything). I think it would be a good idea to have this as an opt-in setting, because renaming properties can easily do more harm than good in a WPF application. It should definitely not be a code annotation attribute because that already exists in the form of the [ForceObfuscate] attribute. Also the new setting should of course be available through the command line.
2. Thanks, that actually works! I've just copied the attribute definitions into our solution anyways - so that's an easy change to make!
3. I understand your argument. But the same could be said about the [ForceObfuscate] attribute. Basically, the argument for having the annotation attributes is that you can tell SmartAssembly - "Hey, I know better than you in this particular situation". You can also break stuff currently by placing incompatible mixes of [ForceObfuscate] in a class hierarchy - or on a public type for that matter. But of course there may be other arguments I'm not aware of.
Anyways, currently, I can achieve what I want by placing a ForceObfuscate attribute on all relevant base AND sub-classes in the desired class hierachy, and It works perfectly. It would be great to have an option to only having to do this on the base class.
4. I think this would be a great addition and vastly increase the number of obfuscated types. I know that an alternative solution is assembly merging but I think that comes with its own set of problems, e.g. creating too many discrepancies/differences between ongoing development/debugging in Visual Studio (where assemblies are not yet merged) and production releases where assemblies are merged, which can lead to subtle runtime bugs. Perhaps it could be achieved by specifying Friend Assemblies in the project file unioned with the InternalsVisibleTo attribute, and then scan for cross assembly type references to determine when and where to rename? (Probably easier said than done )
Since cross assembly renaming basically also enforces that SmartAssembly must produce a set of compatible output assemblies in one go (which is different from now, where always only 1 output assembly is generated), I could be fine with something like this: I specify 1 input main assembly, and 1 output main assembly. Then I switch on the new feature "Cross assembly obfuscation", which then produces 1 output main assembly together with one assembly for each dependency where a dependent public type was renamed. This shouldn't require any structural changes to your project file format, or how user's are used to use your tool in relation to specifying inputs, outputs and dependencies.
- sol
I understand your point re 3, and I'm all in favour of letting people break their own applications in whatever ways they want too . The reality of that situation though is our experience is it causes more issues than it solves.
Regarding 3: with great power comes great responsibility. If you don't know what you're doing, obfuscation in general can cause more issues than it solves.. If SmartAssembly is able to detect those situations that would cause runtime errors, you could either break out of the obfuscation process and tell the user how to fix it; or just skip obfuscating the implicated classes.
So just to summarise, SA-2082, SA-1438, SA-2222 are all on the list and will be looked at soon.
SA-2223 has been fixed and will be released in 7.1.
Do you have a very rough estimate (without committing to anything) on when you will have .NET Core 3 support? Are we talking weeks, months, half a year, a year? Just very roughly, so I can get a feeling of when the other things are likely to receive some degree of attention.
Again, many thanks!
- sol