Today i want to take a quick peek at a new code obfuscation solution for .NET we have been working on.
Back sometime in mid-2009, when we started migrating the Oxygene/Delphi Prism IDE code base to a new managed project system in order to support Visual Studio 2010 and MonoDevelop alongside to the existing Visual Studio 2008 support, we ran into limitations with our existing obfuscation solution (Xenocode). So we started to look for alternatives.
We found Obfuscar, a seemingly abandoned open source project that provided a great feature set and was based on Mono’s Cecil reader/writer library for .NET assemblies — the same library that we’re using for Oxygene and that Carlo had a lot of experience working with (and contributing to). So Carlo took that, expanded it and fixed some issues, and we published the result as a new open source project on code.remobjects.com, our open source SVN repository. Obfuscar, at that stage, was a command line application, and we have been using it in this form for production, for over half a year now (although the August release of Delphi Prism still did ship with XenoCode-obfuscated binaries).
But, we figured, we could do more than that. So we decided to integrate the product with both the IDE and the MSBuild build system, to make obfuscation an integral part of a solution. The result is RemObjects Oxfuscator, the name indicating that it is intended to complement Oxygene — although it will of course work language agnostic on assemblies created with any language (or even those you only have the binary version of).
Let’s See How This Works in Action
Oxfuscator provides it’s own project type, and a new project template that goes along with it. In the most common case, you would use the solution’s Add|New Project… context menu to add an Oxfuscator project to your existing solution, and have obfuscation happen as part of the build. But of course you can also use Oxfuscator on its own, only referencing existing assemblies.
Just as with project references in normal projects, the Oxfuscator project will take part in MSBuild’s automatic dependency resolution, to make sure Oxfuscator runs only after all the projects it depends on have been built.
Oxfuscator will take all the assemblies the project references, and globally obfuscate all shared names, according to the rules defined for it. For every identifier defined in in any of the assemblies, it will generate a new name that is unique (in that scope), and adjust both the definition and all pieces of code that reference that identifier. The result is a new set of classes and types that performs the same function as the old code — but with names that are completely senseless and next to impossible to reverse-engineer.
Oxfuscator provides several settings to provide less readable or completely unreadable identifier names. In the simplest case, they will be made up of gibberish letters, which make no sense to the reader, but are still easily distinguishable (this setting is useful for debugging your obfuscation, as “a”, “aa” and “b” can at least be told apart in Reflector and when seeing them in call stacks and exception messages). In the best case, identifiers will leverage the full power of Unicode and made up of totally illegible characters. Oxfuscator will use all XX different types of whitespaces, as well as obscure punctuation marks, to make sure what your hacker is seeing is, well, almost invisible.
Did i say debugging your obfuscation? Why would you need debugging? Well. maybe not most, but many projects are not completely standalone, but need to interact with external libraries, and thus need certain classes or class members excluded from obfuscation. A good example is our IDE integration for Visual Studio, which, after all, drove Oxfuscator. If Visual Studio loads your project as an add-in and expects it to expose (say) a class called Bar with a method called Foo – well, suffice to say those names better not be obfuscated!
Which brings us to the final topic: exclusions. Oxfuscator provides two ways to exclude certain identifiers from obfuscation. The first, simplest, and (imho) much preferred way – at least if you have access to the code – is to simply decorate your classes or members with the
<code class="codespan">[System.Reflection.Obfuscation(Exclude := true)] attribute, to exclude them from obfuscation. Oxfuscator will automatically detect and honor that. Alternatively, you can specify a list of exclusions “manually” in the project options, as shows here:
Oxfuscator will automatically not obfuscate any identifiers referenced from external assemblies (such as the framework base library itself), including overridden methods or implementations of interfaces defined externally.
When Can You Get it?
Oxfuscator is currently with beta testers, and we’ll talk more about availability, soon. Stay tuned to this space for more.