I'm not sure how obfuscar works internally but I had an idea.
Suppose you have a Type enumerator that iterates over all types in an
assembly and a member enumerator that iterates over all members in a
type. The main loop will iterate all modules (from the settings file)
all types and all members. I guess you have similar code in obfuscar
now.
Then a framework (very small) would allow 'providers' to work with the
assemblies,types and members an each provider decides what has to be
done. So obfuscation would be implemented as a provider. I can also
see providers that check if a type/member is unused and if so remove
it from the target assembly.
I cannot oversee all the details but it appears to be a viable
solution in which a developer can add its own logic that is executed
during an 'assembly-transform'.
What do you think? Would it be a big step from your current code base
to go in this direction?
Grtx,
--Marc
Right now, it's pretty special purpose...built around several loops
that go through the types, renaming bits on each pass. If an option
is added to switch on using unique names instead of the current
smallest-set, this may be a good direction to go when getting it done.
(btw, I've added an issue, re: the unique naming. see
http://code.google.com/p/obfuscar/issues/detail?id=5 )
Anyway, if you need sparring on the architecture.... ;-)
The basic algorithm is currently as follows:
1. Load everything.
2. Group methods.
3. Rename stuff.
4. Save everything.
5. Save the mapping.
The real meat of the current system is the InheritMap and the assembly
handling by the Project class (in steps 1 and 2), which would continue
to be shared by both engines...the part that needs to change is the
series of RenameXXX calls (step 3, currently, made from Program.Main).
The first step I'd like to take is refactoring the current RenameXXX
calls into a behavior, possibly called OverloadingObfuscator or
something similar, that accepts a Project object, and does its
renaming work via a single (or minimal) entry point.
The next step would be implementing a UniqueObfuscator behavior that
implements the same interface and does the same kind of work, but uses
the unique name scheme.
Other project processors could also be created, and there wouldn't be
any reason that multiple project processors couldn't be chained, e.g.,
first the project is handed to DeadCodeEliminator, then to
OverloadingObfuscator, then to StringScrambler, etc.
You need to skip all the types and members that are involved in Xml
Serialization. You have to do this by hand now. Wouldn't it be great I
you could have a provider search for the Xml code attributes and mark
those for the obfuscator provider automatically? There are other areas
of the .NET framework that might also need some attention, like
configuration...
It would require that all provders work on a central "data model" (of
some kind), though....
The only trouble is figuring out which attributes are important and
how to take advantage of them. For example, if a property has the
XmlElement attribute on it, it should be skipped...unless the
XmlElement's ElementName is set, in which case changing the name of
the property is fine.
To make it more complicated, .net has at least 3 different ways to
serialize / annotate your classes to be exposed via xml (including
attributes in System.Xml.Serialization, System.Web.Services, and
System.Runtime.Remoting.Metadata).
I would just make a 'skip-provider' for each category of code
attributes. Make one specifically for Xml-atributes. Then one that
works for web service attributes. If you need to, you just combine
these providers in your obfuscar project settings.