Silverlight - 5 easy steps to obfuscate auto-magically on the build server

Disclaimer
Before you start flaming me, I am aware that all business relevant code and IP stuff must be on the server side. Just funny how much bit**** you see in forums and stackoverflow if you search for "Silverlight obfuscation"

Problem

With tools like Reflector, ILSpy (which is a good Reflector replacement BTW, since Reflector is not free anymore) and Silverlight Spy, it is VERY easy to look into Silverlight XAP files and discover some interesting stuff. We cannot completely hide our source code, but we can at least make it harder to disassemble and see.
If you are a serious Silverlight developer, make sure to get a copy of Silverlight Spy. No, I am not related to them, working for them nor affiliated.

 

Goal

I want to obfuscate my Silverlight client pieces (XAP files) only on the build server.
Our developer machines should not obfuscate during the build in Visual Studio, because we don't want to waste time for obfuscation and have a nice debugging experience.

 

Solution approaches

We have a couple of options. A manual approach with batch-files or powershell-scripts (that would unzip the XAP, obfuscate and rezip the XAP file on each deploy) is bad, since I am a strong believer in automation.

Here the steps how to obfuscate automagically with TFS as a build server

  1. Download Deepsea Obfuscator
  2. Install Deepsea on your dev machine and on your build server (See note how to avoid the install on your Build server)
  3. "Check out" from TFS your Silverlight project (.csproj) and open in Notepad
  4. At the end of the project file add the yellow

-- snip snip snip ---

<ItemGroup> <None Include="Properties\AppManifest.xml" /> </ItemGroup> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Silverlight\$(SilverlightVersion)\Microsoft.Silverlight.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target> --> <!-- XAP Obfuscation starts here --> <Import Project="$(MSBuildExtensionsPath32)\DeepSea Obfuscator\v3\DeepSea.Obfuscator.targets" /> <Target Name="AfterCompile" DependsOnTargets="CopyFilesToOutputDirectory" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <Message Text="Starting DeepSeaObfuscate obj ..." /> <!-- E.g. OBJ\DEBUG\ --> <DeepSeaObfuscate Assemblies="$(ProjectDir)\obj\$(ConfigurationName)\$(TargetFileName)" ReferenceFolders="$(TargetDir)" /> <Message Text="Starting DeepSeaObfuscate bin ..." /> <!-- E.g. BIN\DEBUG\ --> <DeepSeaObfuscate Assemblies="$(TargetPath)" ReferenceFolders="$(TargetDir)" /> <Message Text="Done DeepSeaObfuscate." /> </Target> <!-- XAP Obfuscation ends here --> <ProjectExtensions> <VisualStudio> <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}"> <SilverlightProjectProperties /> </FlavorProperties> </VisualStudio> </ProjectExtensions> </Project>

Do a "check in" and see your Release build output folder with an obfuscated XAP file. WOOT!
Success

If you have a "Deploy to Production" button as per my other blog post, then on your next deployment your Silverlight clients are obfuscated.

 

 

Notes

  1. DeepSea comes with 2 msbuild target files. These are necessary for msbuild.
    If you don't want to install Deepsea on your build server, you can copy those files to the Build server including Deepsea.exe
    C:\Program Files\MSBuild\DeepSea Obfuscator\v3\DeepSea.Obfuscator.targets
    C:\Program Files\MSBuild\DeepSea Obfuscator\v3\DeepSea.Obfuscator.Project.targets
  2. The above msbuild target gets executed after the "CopyFilesToOutputDirectory" target, which I found the best time to obfuscate. Not too early and not too late
  3. We obfuscate single .dll files, that later in the build process get packaged into the final XAP (zip file)
  4. You can customize Deepsea by passing in a ConfigFile. Sample
    <DeepSeaObfuscate Assemblies="$(TargetPath)" ConfigFile="$(SolutionDir)Solution Items\Obfuscation\MySilverlightApp.dsoconfig" ReferenceFolders="$(TargetDir)" />

  5. We obfuscate only on Release build, see the "Condition" filter
    Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">

 

Tip

VS2010 Tools Options Dialog
Figure: For better troubleshooting, set the "msbuild output verbosity" to "Diagnostic", in Tool | Options | Projects and Solutions | Build and Run

 

Why did we choose Deepsea?

We evaluated different Obfuscators: "CodeFort" (199 USD),  ".NET Reactor" (179 USD) and "Eazfuscator" (free).
"Eazfuscator" obfuscated too much, so that the Silverlight couldn't run the app afterwards.
The others were all OK.
In the end we went with Deepsea because they gave an awesome support for all our problems.

 

References

This blog post from Stefan Olson about "Selecting Obfuscators" might help choosing your favorite obfuscation tool.

Check out Andy Beaulieu blog post showing how to use Babel Obfuscator in Visual Studio

 

 

"Look Ma, No source code!"

image
Figure: Reflector crashes trying to disassemble

Latest Posts

Popular Posts