Author Archive

What’s New with Dotfuscator in Visual Studio 2010 Beta 1

Thursday, May 21st, 2009 by Bill Leach

Now that Visual Studio 2010 Beta 1 is officially released, I’m looking forward to hearing feedback from Dotfuscator CE users around the new capabilities we’ve added. First, Dotfuscator CE’s new official name is “Dotfuscator Software Services - Community Edition”. We’ve given it a new name (but here I will still call it “CE” for short) to emphasize its broader focus as a post build tool in this release. We’ve added a whole new class of features and services based on code injection. We’ve given it a new look, reorganizing and simplifying the user interface to improve usability and discoverability. Finally, we’ve improved on the traditional obfuscation functions you may already be using. In this article, I’d like to introduce you to the new code injection features.

Dotfuscator Considered as a Post Build Code Injection Platform

As a tool that already performs significant program analysis and applies binary code transformations, Dotfuscator is in the unique position where it can add value to an application in the post build phase, without necessarily having to write or modify source code. For a while now, Dotfuscator PRO has had these capabilities—and the recently announced Dotfuscator MDE does as well. So I’m happy that Dotfuscator CE is also joining the club. Dotfuscator CE can now inject the following behaviors:

  • Session tracking to determine what applications have been executed, what versions of those applications, and for how long.
  • Feature usage tracking to determine what features are being used, in what sequence, and for how long.
  • Application expiry to encode an end-of-life date, transmit alerts when applications are executed after their expiry date, and terminate expired application sessions. We call this “Shelf Life”.
  • Tamper defense to detect the execution of tampered applications, transmit incident alerts, and terminate tampered sessions.

On the server side, we’ve created a free version of our Runtime Intelligence Services Portal at free.runtimeintelligence.com . To send session tracking, feature usage, and other notifications to the free service, just select the free endpoint as the destination for your messages when configuring Dotfuscator for injection (I’ll show you where to do this below). When you log in to the portal using the company ID you created, you can view the data your application is sending.

A Concrete Example

Let’s use Dotfuscator CE’s new capabilities to add feature analytics to the “hello world” sample application that comes with Dotfuscator CE. The sample application is installed by default into your %Program Files%Microsoft Visual Studio 10.0ApplicationPreEmptive SolutionsDotfuscator Community Editionsamples folder. Since this folder is often not writeable by normal users, I recommend creating a work area under your “Documents” folder and copying HelloWorld.exe and hello_config.xml to it. These are the input application and the associated Dotfuscator configuration file respectively.

Once you’ve done that, launch “Dotfuscator Software Services” from the Visual Studio Tools menu, and open the hello_config.xml file via Dotfuscator File->Open Project menu.

Configuring Feature Analytics

Navigate to the Instrumentation editor by clicking on the Instrumentation node on the left side navigator.

Click on the Options tab, then check “Enable Instrumentation” and “Send application analytics messages”. This tells Dotfuscator to inject code to gather feature usage data as your application runs.

instrumentation_options

You configure the actual code injection via attributes. Attributes can be embedded in the source code using .NET custom attributes (defined in PreEmptive.Attributes.dll, located in the Dotfuscator installation folder). Alternatively, if you don’t want to modify the source code, you can use “extended attributes”, which are maintained through the Dotfuscator UI and stored in your Dotfuscator configuration file. That’s the approach we will use here.

First we will add two attributes at the assembly level that are used to identify and aggregate messages originating from your application. Click on the Attributes tab and highlight the Helloworld.exe assembly. Right click on it and select the “Add Attribute” menu item from the context menu. On the Add Attribute dialog, select both an Application and Business Attribute, then click OK.

instrumentation_addasmattribs

The BusinessAttribute has a CompanyKey, which is a unique value used to identify the creator of the application. Later, you will use this key to log in to the free Runtime Intelligence Services Portal to view your data. You can generate a new unique identifier by pressing the “…” button associated with the CompanyKey entry area. You should also set the CompanyName property to the name of the organization associated with the CompanyKey.  While not required, the name is used to personalize the portal.

Similarly, the ApplicationAttribute has a GUID property that identifies the instrumented application. Again, click on the “…” button associated with the GUID property to generate an application identifier. You can leave the other ApplicationAttributes properties blank.

instrumentation_asmattribs

Now it is time to add two attributes to the Main method, located in the HelloWorld.Hello class. Navigate to that class in the instrumentation editor’s class browser, right click on the Main method, and select Add Attribute from the context menu. Select Setup and Teardown attributes, then click OK.

instrumentation_addsetupattribs

The SetupAttribute should be placed on a method called when the application starts up. When Dotfuscator runs, it injects initialization code into the tagged method. The Main method is usually a good candidate, but that isn’t required—it just needs to be a method that is executed before any messages need to be sent. To configure the SetupAttribute, the only property you need to set is the Custom Endpoint, the remote destination of all messages sent from the application. Click on the “…” button to bring up the Custom Endpoint dialog, and select “PreEmptive’s Free Runtime Intelligence Services” as the endpoint.

instrumentation_customendpoint

The TeardownAttribute can also be placed on the Main method. In general, it should be placed on a method that is called near the end of the application’s lifecycle, after all messages have been sent. Dotfuscator injects cleanup code at the end of the tagged method. Since HelloWorld.exe is a single threaded console application, adding the Teardown attribute to the Main method works, as code at the end of Main is executed last.

Now that we have identified the application and specified the endpoint, we can now add the usage analytics. HelloWorld is a simple application that says Hello and Goodbye—we are interested in how often those two “features” are used (stay with me here, remember this is “hello world”!).

The “Hello” feature is implemented in the HelloWorld.Friendly.SayHello class. Navigate to the method in the instrumentation editor’s class browser. As before, right click to bring up the Add Attribute dialog, but this time select a Feature attribute. Feature attributes tell Dotfuscator where to inject analytics collecting code. Set the attribute’s Name property to “SayHello”. The name you set here shows up in the analytics reports, so choosing a human readable name is important. Leave the FeatureEventType property set to “Tick”. This tells Dotfuscator that the feature is an “instantaneous” event as opposed to an event with a stop and start time.

Now add the same attribute to the HelloWorld.Friendly.SayGoodbye class and name this feature “SayGoodbye”.

instrumentation_featureattribs

Configuration is now complete and you are ready to run Dotfuscator. Press the play button or hit Ctrl-B to build the project.

Now, when you run the application, it will send messages when it starts, stops, and whenever the “SayHello” and “SayGoodbye” methods execute.

Viewing your Data

You can see your data by going to the Free Runtime Intelligence Portal at free.runtimeintelligence.com and logging in with your company key.

Once logged in, you can view your application and feature dashboards to answer questions like:

Which of your applications are being used the most?

portal_appruns

What operating systems are they running on?

portal_oschart

What CLR versions are they running on?

portal_fxchart

How often are your features used?

portal_featurechart

There are also tabular views of the same data for application use:

portal_app_table

And for feature use:

portal_featuretable

Take Away

You’ve seen in the example how you can use Dotfuscator CE in Visual Studio 2010 to implement what amounts to your own “Customer Experience Improvement Program” in your .NET application, with just a few clicks, and without writing any additional code. But I’ve just scratched the surface here– there are lots of other things you can do with this technology. In the coming weeks and months, we will be blogging in-depth about tamper detection, shelf-life, and application analytics.  In the meantime, I encourage you to play with Dotfuscator CE yourself in the Visual Studio 2010 Beta and give us your feedback!

Dotfuscator and MSBuild

Friday, May 1st, 2009 by Bill Leach

This is the first in a series of what I hope to be informative postings around the theme of “Dotfuscator Tips, Tricks, and HOWTOs”.  Today’s topic, if you missed the title, is MSBuild integration.  Dotfuscator Pro ships with an MSBuild task that is by default installed into the MSBuildExtensionsPath directory (e.g. C:\Program Files\MSBuild) under “PreEmptive\Dotfuscator\4.0”. In this directory, you will also find PreEmptive.Dotfuscator.Targets, the file that contains a common definition for the “Dotfuscate” target.

Dotfuscator’s user’s guide contains a reference for the Dotfuscate task, describing its inputs and outputs, but does not contain any examples. I hope to rectify that here with some working examples that demonstrate how to use the Dotfuscate task to its full potential. I’m assuming that you are familiar with MSBuild and have used Dotfuscator.

Dotfuscator Project Files in Visual Studio

First off, if you want a quick look at an MSBuild script that uses Dotfuscator and you are using Dotfuscator’s Visual Studio integration (VS 2005 and above), you should know that the Dotfuscator project file is persisted in MSBuild format. In fact, you can take any solution that contains a Dotfuscator project and feed it to MSBuild on the command line—MSBuild will build the solution the same as it does inside Visual Studio, including the Dotfuscation step.

Dotfuscator project files have a “.dotfuproj” file extension. If you open one in a text editor, you will see that it defines an MSBuild Project whose default target is “Dotfuscate”. It defines several property and item groups, then imports the PreEmptive.Dotfuscator.Targets file. It turns out that many of the property and item groups are defined primarily for Dotfuscator’s internal use when integrating with Visual Studio and are not strictly required for MSBuild. Let’s take out the extra things and build a minimal MSBuild script for invoking Dotfuscator.

The Bare Minimum

Here is a minimal MSBuild script that invokes Dotfuscator.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Dotfuscate" ToolsVersion="3.5">
<PropertyGroup>
<DotfuscatorBinPath>$(MSBuildExtensionsPath)\PreEmptive\Dotfuscator\4.0</DotfuscatorBinPath>
<DotfuscatorDataPath>$(MSBuildExtensionsPath)\PreEmptive\Dotfuscator\4.0</DotfuscatorDataPath>
</PropertyGroup>
<PropertyGroup>
<!– Required: specify path to dotfuscator configuration file –>
<ConfigPath>.\dotfconfig.xml</ConfigPath>
</PropertyGroup>
<Import Project="$(DotfuscatorDataPath)\PreEmptive.Dotfuscator.Targets" />
</Project>

The first two properties are required to locate the Dotfuscator targets file and MSBuild task DLL. Beyond that, the only other required property is “ConfigPath”, which should be set to the location of your Dotfuscator configuration file. In this example, the Dotfuscator configuration file is located in the same directory as the MSBuild script, and is called dotfconfig.xml.

For maximum flexibility, Dotfuscator’s MSBuild task is designed so that it consumes the same Dotfuscator configuration files that the command line interface consumes. These are the same files that the Visual Studio and standalone user interfaces generate for you when you configure a Dotfuscator project.

If you save this file and run MSBuild on it, MSBuild will use the default target, “Dotfuscate”, which is defined in the imported targets file. Assuming the referenced Dotfuscator configuration file exists, Dotfuscator will run as configured.

Build Integration

Typically, you will want to run Dotfuscator as part of a larger build process. For example, you might not want a separate Dotfuscate target—perhaps you want to run Dotfuscator as part of another build step. You might also want to do something with the Dotfuscated output assemblies, such as copy them to a staging directory.

The next examples demonstrate these build integration scenarios by invoking the Dotfuscate task and using its output properties. First, let’s look at an example that runs the Dotfuscate task through a dependency relationship on a “Custom” build target.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Custom" ToolsVersion="3.5">
<PropertyGroup>
<DotfuscatorBinPath>$(MSBuildExtensionsPath)\PreEmptive\Dotfuscator\4.0</DotfuscatorBinPath>
<DotfuscatorDataPath>$(MSBuildExtensionsPath)\PreEmptive\Dotfuscator\4.0</DotfuscatorDataPath>
</PropertyGroup>
<PropertyGroup>
<ConfigPath>.\dotfconfig.xml</ConfigPath>
</PropertyGroup>

<Import Project="$(DotfuscatorDataPath)\PreEmptive.Dotfuscator.Targets" />

<!– Create a ‘Custom’ target that depends on the Dotfuscate target.  After running, the Dotfuscate task outputs are available –>
<Target Name="Custom" DependsOnTargets="Dotfuscate">

<!– Access outputs from Dotfuscator task (map file, output assemblies, output debug symbols, etc.–>
<Message Text="Dotfuscator Mapping File: @(DotfuscatorMappingFile)" />
<Message Text="Dotfuscated Output Assemblies: @(DotfuscatedAssemblies)" />
<Message Text="Dotfuscated Debug Symbols: @(DotfuscatedDebugSymbols)" />

</Target>
</Project>

Running MSBuild on this script invokes the “Custom” target. Since “Custom” depends on the “Dotfuscate” target, “Dotfuscate” is invoked first. Once that’s done, you can manipulate the Dotfuscate target’s outputs. The MSBuild Task Reference in the Dotfuscator User’s Guide documents the complete list of available outputs. You can also see them directly by opening up the PreEmptive.Dotfuscator.Targets file in a text editor. This example simply displays the paths of the renaming map file, the output assemblies, and the associated PDB files.

Up until now, the examples have invoked Dotfuscator implicitly by referencing the Dotfuscate target defined in PreEmptive.Dotfuscator.Targets. You can also invoke the Dotfuscate task explicitly from your own target. This example demonstrates:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="3.5">
<PropertyGroup>
<DotfuscatorBinPath>$(MSBuildExtensionsPath)\PreEmptive\Dotfuscator\4.0</DotfuscatorBinPath>
<DotfuscatorDataPath>$(MSBuildExtensionsPath)\PreEmptive\Dotfuscator\4.0</DotfuscatorDataPath>
</PropertyGroup>
<PropertyGroup>
<ConfigPath>.\dotfconfig_explicit.xml</ConfigPath>
</PropertyGroup>

<!– This targets file defines the Dotfuscate task –>
<Import Project="$(DotfuscatorDataPath)\PreEmptive.Dotfuscator.Targets" />

<!– Explicitly invoke the Dotfuscate target from this target –>
<Target Name="Build">

<!–
You can do other stuff here, before invoking Dotfuscate

–>

<Dotfuscate ConfigPath="$(ConfigPath)">
<Output TaskParameter="OutputAssemblies" ItemName="DotfuscatedAssemblies" />
</Dotfuscate>

<!– Copy output assemblies to a staging directory.–>
<PropertyGroup>
<StagingDir>.\staging</StagingDir>
</PropertyGroup>

<MakeDir Directories="$(StagingDir)" />

<Copy SourceFiles="@(DotfuscatedAssemblies)" DestinationFolder="$(StagingDir)" />

</Target>
</Project>

Here we are invoking the Dotfuscator task directly in the “Build” target. We’ve essentially copied the definition of the Dotfuscate target out of the PreEmptive.Dotfuscator.Targets file and stripped out the things we aren’t using (for brevity). After Dotfuscator runs, the script creates a staging directory and uses MSBuild’s Copy task to copy the Dotfuscated output assemblies to it.

Setting Dotfuscator Properties from MSBuild Scripts

As you may know, Dotfuscator has its own string macro facility, called properties. These shouldn’t be confused with MSBuild properties. Dotfuscator properties are primarily a means for making Dotfuscator configuration files more general and more portable. Configuration files can reference properties in any element that takes a file name or directory; they can also define properties– but properties become more powerful when the definition is passed in as Dotfuscator is invoked. For example, you can define properties from Dotfuscator’s command line interface using the /p switch. Not surprisingly, you can also define properties from MSBuild scripts. This is what the Dotfuscate Task’s “Properties” property is for.

For example, let’s assume you have a Dotfuscator configuration file that specifies the renaming map file like this:

<!– "configdir" is a built-in Dotfuscator property that is always the directory of the configuration file –>
<mapoutput overwrite="false">
<file dir="${configdir}\${reportdir}" name="map.xml" />
</mapoutput>

The location of the renaming map file is a subdirectory (whose name will be provided in the “reportdir” property) of the configuration file’s directory.

Now, in your MSBuild script, define an MSBuild Property (in this case, called “MyDotfuscatorProperties”). Inside that property, define each Dotfuscator property using its name as an XML element, and its value as content. Content can consist of any text, including MSBuild property references. For example:

<PropertyGroup>
<MyDotfuscatorProperties>
<reportdir>Reports</reportdir>
<mypropertyname>$(MyMSBuildProperty)</mypropertyname>
</MyDotfuscatorProperties>
</PropertyGroup>

This example defines two Dotfuscator properties:

  1. reportdir = Reports
  2. mypropertyname = content of MyMSBuildProperty

Next, when invoking the Dotfuscate task, set its “Properties” property to the value of the MSBuild property you just defined:

<Dotfuscate ConfigPath="$(ConfigPath)" Properties="$(MyDotfuscatorProperties)">
<Output TaskParameter="OutputAssemblies" ItemName="DotfuscatedAssemblies" />
</Dotfuscate>

Putting all this together and running MSBuild, Dotfuscator writes the renaming map file to a subdirectory named “Reports”.

Conclusion

Hopefully I have shed some light onto the process of using Dotfuscator with MSBuild. I’d like to expand on this introduction in future posts, so let me know what you’d like to see. I welcome your suggestions, questions, and comments– MSBuild related or not!