Getting Started
Understanding Protection
Understanding Obfuscation
Understanding Checks
Understanding Instrumentation
Using the GUI
References
Note: These instructions cover both Professional Edition and Community Edition of Dotfuscator.
These instructions will walk you through how to get started using Dotfuscator to protect a Xamarin project. After you're done, the protection process will be integrated into your project, so whenever you build the project in Visual Studio or MSBuild, Dotfuscator will automatically protect it. You can apply these steps to each platform your app supports, creating an app with a proven, layered protection strategy, no matter what device it's running on.
Note: This Dotfuscator-Xamarin integration has been designed to work on Android, iOS, and the Universal Windows Platform (UWP). Other platforms, particularly Windows 8.x platforms, are not supported by these instructions.
The example for these instructions will be a Xamarin.Forms sample app named BugSweeper. It's a classic game, this time targeting Android, iOS, and Windows 10 devices.
There are a few ways to follow along with these instructions:
You can download BugSweeper yourself and step through these instructions.
You can download the git repository we made while writing these instructions to see how these instructions are applied at every step.
You can apply these instructions to your own app, using this as a reference.
You can click the screenshots in these instructions to view them at their full sizes.
First, download the BugSweeper ZIP archive from the Xamarin website and extract it to a new directory (example: C:\code\BugSweeper
).
You can then add the directory to local source control (such as a git repository).
Next, open the BugSweeper.sln
solution file in Visual Studio 2017.
Upon doing so, you'll get a warning saying that Windows 8.x projects will not load:
Click OK and finish loading the solution.
Note: You may receive another warning, stating that you need to download Universal Windows Platform (UWP) components in order to open a project in this solution. If you are not developing your Xamarin app to target UWP, then you can ignore this warning and continue through the instructions, ignoring steps about the
BugSweeper.UWP
project.
Solution Explorer shows the projects in the solution:
The solution consists of a Portable Class Library (PCL) and several platform-specific output projects that reference the PCL:
BugSweeper
is the PCL that contains shared game logic and platform-agnostic business logic.
BugSweeper.Android
is an output project for Android devices.
BugSweeper.iOS
is an output project for iOS devices.
FormsTemplateiOS
.
We recommend changing it to BugSweeper.iOS
for consistency.BugSweeper.UWP
is an output project for the Universal Windows Platform (e.g., Windows 10).
Note that the output assembly for this project is named BugSweeper.WinUniversal
.
This project targets build 10.0.10240.0
.
If you retarget it, do not target build 10.0.15063
(the Creators Update) or later if you are using earlier versions of Dotfuscator (versions before Community Edition 5.30.0, or Professional Edition 4.31.0).
That build's reference paths are not supported by the earlier versions of Dotfuscator.
Later releases of Dotfuscator have addressed this issue.
As indicated by the warning when opening the solution, the remaining projects (BugSweeper.Windows
, BugSweeper.WinPhone
, and BugSweeper.WinPhone81
) do not load because Visual Studio 2017 does not support their platforms.
Per the note at the top of this page, these instructions don't support those platforms either.
Remove the unsupported projects from the solution, save the solution, and remove the relevant project directories from local source control.
With the all of the supported projects loaded, test building and running the app to make sure it works as intended (and definitely not just to have an excuse to play the game during work hours).
Once you've done that, it's time to protect the app.
Before you can start integrating Dotfuscator into the Xamarin build pipeline, you need to decide what projects, and what configurations of those projects, you want to protect. Then there are some technical prerequisites: you must first install Dotfuscator and enable its command line interface, as well as download the necessary MSBuild targets file.
Visual Studio solutions consist of multiple projects, each of which produces a .NET assembly. Each project can be built in multiple configurations, such as Debug or Release.
The Dotfuscator-Xamarin protection described in these instructions operates on a single project/configuration combination at a time. You therefore should, at the outset, decide what projects and configurations will be protected. Here are some guidelines for choosing:
You should only apply Dotfuscator to projects intended for distribution, not to internal libraries. When protecting an output project (e.g., an Android app), Dotfuscator also protects that project's copies of its dependencies (e.g., shared libraries).
You should apply Dotfuscator to all releasable build configurations. You want all builds given to the public to be protected. For details on how to release a protected build, see this section at the end of the page.
You should NOT apply Dotfuscator to builds meant for debugging. Dotfuscator's obfuscation makes debugging much more difficult, if not impossible, even when the source code is available.
You should NOT apply Dotfuscator to builds used by team members who will not have Dotfuscator installed. When Dotfuscator is integrated into a project/configuration, Dotfuscator will become a dependency of building that project/configuration. Therefore, every machine that builds that project/configuration must have Dotfuscator installed.
For the example, we suggest protecting:
BugSweeper.Android
in the Release configuration
BugSweeper.iOS
in the Release, Ad-Hoc, and AppStore configurations
BugSweeper.UWP
in the Release configuration
For future reference, we'll call these the projects and configurations to protect. When you're done, these will be your protected projects and configurations.
But what about protecting the shared code in the BugSweeper
portable class library?
Well, because each output project references the PCL, the unobfuscated PCL will be copied to the output project's binary directory.
The integration will then obfuscate both the unobfuscated PCL copy and the unobfuscated platform-specific assembly at the same time.
This way, the PCL is also protected when it is packaged within an app for the given platform.
Each machine that will be building a protected project/configuration combination will need to have Dotfuscator installed, with that installation's command line interface active.
Dotfuscator comes in two editions: the free Community Edition and the commercially-licensed Professional Edition. Your entire team should use the same edition to ensure the same level of protection no matter who builds the app.
Note: The Dotfuscator Community Edition license expressly prohibits use by commercial organizations for anything other than personal research and education. If you would like to use Dotfuscator on commercial projects, please consider evaluating Dotfuscator Professional Edition.
The screenshots shown throughout these instructions reflect Professional Edition, unless otherwise mentioned.
Install the version of Dotfuscator that you will be using. See the Dotfuscator Community Edition installation page for help installing CE and the Dotfuscator Downloads page to download the latest installer for Dotfuscator Professional Edition. You can also request an evaluation of Professional Edition.
Once, installed you need to register your copy of Dotfuscator CE or register your copy of Dotfuscator Professional Edition.
Locate the command line interface's directory.
In Dotfuscator Professional Edition this will be in the directory where you installed Dotfuscator, normally something like C:\Program Files (x86)\PreEmptive Solutions\Dotfuscator Professional Edition 4.28.0
.
Instructions for this step in Dotfuscator CE can be found here.
Note the absolute path to the command line interface executable - this is the Dotfuscator CLI path, which will be needed later.
For Dotfuscator Professional Edition the command line interface is dotfuscator.exe
, for Community Edition the command line interface is dotfuscatorCLI.exe
.
You may want to verify that the command line interface is active.
From the command line window, run the executable from step 4 followed by the argument /?
.
E.g. for Dotfuscator Professional Edition run dotfuscator.exe /?
and verify that before the usage instructions that a message similar to the following does not appear:
You must register Dotfuscator in order to execute command line builds.
Run the Dotfuscator GUI which will explain how to register.
After installing Dotfuscator, you'll also need to download the following Dotfuscator-Xamarin MSBuild targets file:
PreEmptive.Dotfuscator.Xamarin.targets
- DownloadWe recommend saving it in your app's solution directory and adding it to your local source control, as it will be required for building your projects. The path to this file is the targets file path.
For our example, we save it as C:\code\BugSweeper\PreEmptive.Dotfuscator.Xamarin.targets
and add it to local source control.
Earlier, you decided what projects you wanted to protect. We recommend following the remaining steps in these instructions with one of those projects at a time. Later, you'll repeat the process for each remaining project -- we'll tell you when it's time to do this.
Our example from here on will focus on BugSweeper.Android
, though we will also mention details required for iOS and UWP projects.
Before you continue, it can be helpful to learn what a reverse-engineer can see in a normal, unprotected app. After you integrate Dotfuscator into the build pipeline, you will repeat these steps to demonstrate how the app has been protected.
To view a decompiled version of your app:
If you haven't already, build your project from Visual Studio.
Download the .NET decompiler ILSpy.
Extract the ZIP archive and run ILSpy.exe
.
In the ILSpy interface, open the File menu and select Open....
Browse to an output assembly binary directory (example: C:\code\BugSweeper\BugSweeper\BugSweeper.Android\bin\Release
) and select assemblies corresponding to your projects (example: BugSweeper.dll
and BugSweeper.Android.dll
).
Using the code tree, explore the contents of your assemblies. Note the resemblance to the original source code: private member and local variable names are preserved, and the control flow is essentially the same.
Close ILSpy, as it can sometimes conflict with Visual Studio's access to the assemblies on the filesystem.
Now it's time to actually integrate Dotfuscator into your Xamarin project.
You'll do this by editing your Visual Studio project file (example: BugSweeper.Android.csproj
).
Each Visual Studio project file is an XML file containing MSBuild definitions. You can add the Dotfuscator-Xamarin integration to the project by importing the downloaded targets file into the project file.
To import the Dotfuscator-Xamarin MSBuild targets file:
Open your app's solution in Visual Studio.
In Solution Explorer, right-click on the project you want to protect (example: BugSweeper.Android
) and select Unload Project.
In Solution Explorer, right-click on the project again and select Edit ProjectFilename (example: Edit BugSweeper.Android.csproj).
The project file appears in an XML editor.
Right-click on the file's tab and select Open Containing Folder.
File Explorer opens the project directory (example: C:\code\BugSweeper\BugSweeper\BugSweeper.Android
).
Determine the relative path from the project directory to the targets file path (example: ..\..\PreEmptive.Dotfuscator.Xamarin.targets
).
Return to Visual Studio and scroll to the end of the project file.
Immediately before the </Project>
tag, insert the following line, substituting the relative path from step 7 appropriately:
<Import Project="..\..\PreEmptive.Dotfuscator.Xamarin.targets"/>
Save the file.
At this point, the Dotfuscator-Xamarin integration is included in the project; however, it is not enabled by default. You can enable the protection process, as well as set some additional parameters, using MSBuild properties.
MSBuild properties are defined in <PropertyGroup>
tags throughout the project file.
For instance, consider this excerpt:
<PropertyGroup>
<AssemblyName>BugSweeper.Android</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
</PropertyGroup>
There are three <PropertyGroup>
sections defined here: a section that's always applied, a section that's applied if the project configuration is Debug, and a section that's applied if the project configuration is Release.
The output assembly name will always be BugSweeper.Android
, but the path to that assembly varies between the two configurations (bin\Debug\
for a Debug configuration, bin\Release\
for a Release configuration).
Note: In addition to the
Configuration
property, the project file also references aPlatform
property. This is not the platform in the sense used in these instructions, but rather the device that the build is for. For instance, an iOS project defines separate<PropertyGroup>
s for the Release project configuration running in an iPhone Simulator and running on an iPhone, but all builds of this project target the iOS platform:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' "> <DebugType>none</DebugType> <CodesignEntitlements /> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' "> <DebugType>none</DebugType> <CodesignKey>iPhone Developer</CodesignKey> </PropertyGroup>
There are several MSBuild properties recognized by the Dotfuscator-Xamarin integration. To set them:
In Visual Studio, scroll to the top of the project file.
Locate a <PropertyGroup>
with no Condition
attribute.
In this section, add the following tags:
<DotfuscatorXamarinCliPath>Dotfuscator CLI Path</DotfuscatorXamarinCliPath>
, substituting the value for the Dotfuscator CLI path noted when setting up Dotfuscator.
<DotfuscatorXamarinConfigFileName>DotfuscatorConfig.xml</DotfuscatorXamarinConfigFileName>
<DotfuscatorXamarinGenerateNewConfigFile>true</DotfuscatorXamarinGenerateNewConfigFile>
Locate all of the <PropertyGroup>
sections corresponding to configurations to protect for this project, per your earlier decision.
If there are multiple <PropertyGroup>
s that correspond to a build configuration to protect, locate all of them.
For instance, we chose to protect BugSweeper.iOS
in the Release, Ad-Hoc, and AppStore configurations, so when we perform this step on that project, we would locate the sections beginning with the following tags:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
Note that we included both Release configuration sections: the first for an iPhone Simulator, and the second for a physical iPhone. The remaining configurations (Ad-Hoc and AppStore) only have one section each, for a physical iPhone.
For the example, we chose to protect the project (BugSweeper.Android
) in just the Release configuration, so we locate the <PropertyGroup>
section beginning with the following tag:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
In each of the sections located in step 4, add the following tag:
<DotfuscatorXamarinEnabled>true</DotfuscatorXamarinEnabled>
Save the file.
At this point in the process, the Dotfuscator config file does not exist. It will later be generated by the Dotfuscator-Xamarin integration when the protected build is first run.
However, while you're in the project file, you should take a moment to add the config file's path to the project's tracking. This way, once the config file exists, Visual Studio will take it into account when determining whether to rebuild your app or, when there's no changes, skip doing so to save time.
To make your project track the Dotfuscator config file:
In Visual Studio, locate the last <ItemGroup>
tag in the project file.
After that tag closes, add the following:
<ItemGroup>
<None Include="DotfuscatorConfig.xml" />
</ItemGroup>
Save the project.
Now you can build the project with protection enabled. To do so:
In Visual Studio, close the project file.
In Solution Explorer, right-click on the protected project (example: BugSweeper.Android
) and select Reload Project.
Using the Solution Configurations, Solution Platforms, and Startup Projects drop-downs, put your solution in a configuration that will exercise the protected build configuration (example: Release, Any CPU, BugSweeper.Android
).
In Solution Explorer, right-click on the protected project and select Build.
When the build completes, note text similar to the following in the Output tab:
2> Running Dotfuscator with a new config file based on project references...
2> Finished running Dotfuscator with a new config file.
2>C:\code\BugSweeper\BugSweeper\BugSweeper.Android\BugSweeper.Android.csproj : warning : A new Dotfuscator config file was generated because it did not exist: 'DotfuscatorConfig.xml'.
Note that this text only appears when DotfuscatorConfig.xml
doesn't exist.
Later builds (that are not skipped due to all files being up-to-date) will produce different text:
2> Running Dotfuscator with config file 'DotfuscatorConfig.xml'...
2> Finished running Dotfuscator.
Note that your MSBuild project build output verbosity affects the display of this text. These instructions assume the default of Minimal. If this is set to Quiet, only the initial build's warning will appear. If this is set to Normal or more detailed, additional lines of text will appear interleaved among these lines.
If you still do not see these lines of text after adjusting the verbosity, check the following before rebuilding:
Ensure you are building the project whose file you modified (example: BugSweeper.Android
).
Ensure you are building a protected configuration of that project (example: Release).
Ensure that Dotfuscator's command line interface is enabled (see the relevant section: Setting up Dotfuscator .
Ensure the changes to the project file were saved by viewing the file (example: C:\code\BugSweeper\BugSweeper\BugSweeper.Android\BugSweeper.Android.csproj
) in a text editor and checking for the changes made earlier in this section.
If you see an error message:
If the error says the Dotfuscator process exited with an error code, you can get more information by setting the verbosity to Normal. When you rebuild, if you see an error like this:
2> [Build Output] Couldn't load external type because its assembly can't be found
...then see the Handle Reference Errors During Build section.
Ensure that an unprotected configuration rebuilds successfully. If it does not, then there is likely a problem in the regular build, not the protection step.
In Solution Explorer, under the protected project, note that the DotfuscatorConfig.xml
file has been added.
This is the Dotfuscator config file, which determines how protection is performed on your project.
BugSweeper.Android.dll
), as well as all assemblies derived from projects that the selected project directly references (example: the BugSweeper.dll
portable class library).
Other assemblies, including those derived from projects that the selected project indirectly references, are also protected by default as of Version 1.1.0 of the PreEmptive.Dotfuscator.Xamarin.Targets file.Add that new Dotfuscator config file to local source control.
In Solution Explorer, right-click on the protected project and select Open Folder in File Explorer.
In the project directory shown, note the presence of a new subdirectory, DotfuscatorReports
.
This directory contains reports generated during the obfuscation process, including the renaming map file (Renaming.xml
), which indicates how code elements were renamed.
If not already ignored, add that new subdirectory to your local source control's ignore list.
At this point, Dotfuscator is integrated into the Xamarin build process for this project. However, you likely will still need to configure the protection to suit your app and ensure correct behavior at runtime. See the renaming exclusion example page for details on figuring out renaming exclusions for a project.
At this point, you can re-inspect your assemblies by repeating the steps in the View the Unprotected Assembly section. This time, your assembly should provide much less information than it previously did.
In Community Edition, internal types, private fields, and local variables will no longer have their original names, removing semantic information about your code:
In Professional Edition, all the protection of Community Edition applies, and control flow will also be jumbled, making the logic difficult to follow:
If you're using Professional Edition, you can configure additional obfuscation features before moving on. This will create an assembly that's even harder to reverse-engineer.
Now that you've protected your app during builds on your machine, you will need to add this protection step to all relevant builds done by your team.
Note: All machines that build a protected project/configuration combination must have Dotfuscator installed and activated.
If not already done so, you should check the following items into local source control, given $
as the repository root (example: C:\code\BugSweeper\
):
$\PreEmptive.Dotfuscator.Xamarin.targets
).$\BugSweeper\BugSweeper.Android\DotfuscatorConfig.xml
).You should have your source control ignore the following:
$\BugSweeper\BugSweeper.Android\DotfuscatorReports\
, or all directories named DotfuscatorReports\
).In a later step, you will push these changes to the rest of your team.
The Dotfuscator-Xamarin integration automatically generates a Dotfuscator config file if one isn't present. This is helpful when initially setting up the integration, but once a config file has been established, this feature can cause subtle problems.
For instance, suppose that, by accident, the Dotfuscator config file is removed from source control. Then, whenever the build server goes to build the project, it cannot find the config file, so the integration generates a new one and uses that. Any configuration customizations you've made will be lost, and your build server may be creating an app that doesn't operate correctly.
In this case, it would be preferable for the build to fail loudly, rather than just continue on with a default config file and emit a warning. That way, your team would know as soon as possible that there's something wrong with the build process, and re-add the config file to source control.
To disable Dotfuscator config file generation and cause an error if the config file is not present:
Open your app's solution in Visual Studio.
In Solution Explorer, right-click on the project that is being protected (example: BugSweeper.Android
) and select Unload Project.
In Solution Explorer, right-click on the project again and select Edit ProjectFilename (example: Edit BugSweeper.Android.csproj).
The project file appears in an XML editor.
Locate the <DotfuscatorXamarinGenerateNewConfigFile>
tag and change its value from true
to false
.
Save and close the project file.
In Solution Explorer, right-click on the protected project (example: BugSweeper.Android
) and select Reload Project.
Commit your changes to the project file to local source control.
You can now share your local source control changes to the rest of your team (example: git push
).
Provided Dotfuscator is installed on your teammates' machines, builds will be protected automatically.
This also applies to build machines, provided they are using Visual Studio or MSBuild to build the projects.
At this point, you should repeat these instructions, starting from the Select a Project section, for the remaining output projects you chose to protect.
For example, let's say we just finished protecting BugSweeper.Android
.
We now repeat these instructions for BugSweeper.iOS
, then for BugSweeper.UWP
.
This section gives general advice for developing your app further once you have Dotfuscator's protection in place for your output projects.
As you develop your app, you may need to adjust Dotfuscator's renaming exclusions due to new or modified code. Follow the instructions on configuring renaming exclusions as appropriate.
In addition to the renaming protection used by both editions of Dotfuscator, Dotfuscator Professional Edition also offers various other obfuscation and protection features.
The default config file generated by the Dotfuscator-Xamarin integration enables control flow obfuscation, but excludes control flow transforms that are incompatible with Mono (as Xamarin is based on the Mono runtime). You can also enable other protection features.
To change how Dotfuscator Professional Edition protects your projects:
From Visual Studio, build the output project you want to modify, in all protected configurations.
Open the Professional Edition user interface (from the Start Menu, search for Dotfuscator Professional Edition).
In the user interface, open the File menu and Open the Dotfuscator config file corresponding to the project you want to modify (example: C:\code\BugSweeper\BugSweeper\BugSweeper.Android\DotfuscatorConfig.xml
).
On the Settings tab, on the Global Options page, enable or disable protection features under the Feature section.
Important: As these property names are expressed as Disable
Check the feature-specific documentation for whether Xamarin is supported.
Configure the features under their various tabs.
Note that the Renaming and Control Flow obfuscation, when enabled, default to protecting all code in the input assemblies. All other obfuscation features, such as String Encryption, require additional configuration to include specific code elements to protect.
For details, see the various subsections of the Configuring Dotfuscator via the GUI section of the Dotfuscator Professional Edition User Guide.
When ready to build, save the config file, then build the project from Visual Studio.
After you're satisfied with your changes, commit the updated config file to source control and share the changes to the rest of your team.
When you first integrate Dotfuscator with your Xamarin project, a Dotfuscator config file is automatically generated. This generated config file specifies which assemblies will be protected for the given output project:
The assembly of the output project itself (example: BugSweeper.Android.dll
), and
All assemblies derived from other projects in the solution that the output project directly and indirectly refers to (example: BugSweeper.dll
, the portable class library).
There is one scenario where this list of input assemblies may need to be manually updated: If you add a new project reference to the output project (the config file is not regenerated with this new reference).
Note: Previously, if you wanted to protect assemblies that are not directly referenced by the output project, but are nonetheless packaged with the app package, you needed to add the input assemblies manually. As of PreEmptive.Dotfuscator.Xamarin.targets version 1.1.0, that is no longer needed, the targets file adds assemblies that are indirectly referenced as default inputs to Dotfuscator.
Consider our example.
Let's say we want to split the Tile
class, and the images it refers to, out of the BugSweeper
portable class library into a separate BugSweeperTile
PCL.
After doing so, the Tile
class will no longer be protected in our BugSweeper.Android
, BugSweeper.iOS
, or BugSweeper.UWP
builds, because it is in the new BugSweeperTile
assembly.
To rectify this and bring the library under protection:
From Visual Studio, build your output projects in all protected configurations.
Open Dotfuscator's user interface:
For Community Edition, from Visual Studio, open the Tools menu and select PreEmptive Protection - Dotfuscator.
For Professional Edition, run Dotfuscator Professional Edition from the Start Menu.
In the user interface, open the File menu and Open the Dotfuscator config file (example: C:\code\BugSweeper\BugSweeper\BugSweeper.Android\DotfuscatorConfig.xml
).
Navigate to the Project Properties screen.
For Community Edition: Select Properties from the navigation tree, then select the Project Properties tab if it is not already selected.
For Professional Edition: Select the Settings tab, then select Project Properties from the navigation tree.
Note the paths displayed for the External Property configdir
and the Project Property InDir
.
Concatenated, this is the Dotfuscator input directory (example: C:\code\BugSweeper\BugSweeper\BugSweeper.Android\obj\Release\DotfuscatorXamarin\dfin
).
Navigate to the Inputs screen.
For CE: Select Inputs from the navigation tree.
For Pro: Select the Input tab.
Click the Add Input button (Community Edition: , Professional Edition: ).
Browse to the Dotfuscator input directory and select the assembly to add to protection (example: BugSweeperTile.dll
).
After adding the assembly by its absolute path, click the Edit Input button and replace the drive and directory part of the path with ${configdir}\${InDir}\
(example: ${configdir}\${InDir}\BugSweeperTile.dll
).
Save the config file.
Repeat from step 3 for all output projects (example: C:\code\BugSweeper\BugSweeper\BugSweeper.iOS\DotfuscatorConfig.xml
, then C:\code\BugSweeper\BugSweeper\BugSweeper.UWP\DotfuscatorConfig.xml
).
Now, the protected builds will also protect the new assembly when packaged into an output project. You can verify this using the steps in the View the Protected Assembly section.
Recent updates to Visual Studio have changed the way Xamarin reference assemblies are stored. This can cause an issue with older versions of Dotfuscator, where these reference assemblies cannot be found. The issue causes the integrated project to encounter an error when built from Visual Studio.
If you encounter a build error, details can be seen by setting the build verbosity to Normal. The issue discussed by this section is indicated by an error such as the following:
2> [Build Output] Couldn't load external type because its assembly can't be found: Android.Content.PM.ConfigChanges,Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=84e04ff9cfb79065 (TaskId:173)
In this case, Dotfuscator cannot locate the type ConfigChanges
in the Xamarin reference assembly Mono.Android
.
Visual Studio 2017 can locate it in its own reference assembly path, such as C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\ReferenceAssemblies\
Microsoft\Framework\MonoAndroid\v6.0
, but older versions of Dotfuscator only look in the common reference assembly path, such as C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v6.0
.
First, ensure you are using the latest version of Dotfuscator. Newer versions of Dotfuscator address this issue. See the Dotfuscator Downloads page for updates to both Community Edition and Professional Edition.
Otherwise, there is a workaround as follows:
Open a command prompt as an Administrator.
Create a subdirectory in the common reference assembly path for assemblies defined in Visual Studio 2017:
mkdir "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\VS2017"
Change the active directory to the Visual Studio 2017 framework reference assembly directory. For instance, if you installed Visual Studio 2017 Professional in its default location:
cd "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\ReferenceAssemblies\Microsoft\Framework"
Run the following command to create directory symbolic links from the common reference assembly path to the Visual Studio 2017 reference assembly path:
for /d %G in (*) do mklink /d "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\VS2017\%G" "%CD%\%G"
An alternative workaround exists in Professional Edition only:
Open the Professional Edition user interface by running Dotfuscator Professional Edition from the Start Menu.
In the user interface, open the File menu and Open the Dotfuscator config file (example: C:\code\BugSweeper\BugSweeper\BugSweeper.Android\DotfuscatorConfig.xml
).
On the Settings tab, select User Defined Assembly Load Path from the navigation tree.
Click the Add assembly load path icon () and add a path that Dotfuscator should probe (example: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\ReferenceAssemblies\
Microsoft\Framework\MonoAndroid\v6.0
).
Save the config file (from the File menu).
Click the Build icon to see if Dotfuscator generates any further errors.
Repeat from step 4 for all necessary directories.
When you are ready to release your app:
Build and package your app as normal for each output project.
Copy the report files from each project's DotfuscatorReports\
directory to a secure location associated with the release and the project.
Do NOT distribute these files to end-users; they contain information that can be used to reverse the renaming obfuscation, among other things.
BugSweeper
, we may archive the contents of C:\code\BugSweeper\BugSweeper\BugSweeper.Android\DotfuscatorReports
to \\company_network_share\release_artifacts\BugSweeper\2.0\Android\DotfuscatorReports
.Release your app as normal.
When troubleshooting issues with a stack trace, use the archived Renaming.xml
file to determine the original source code names of code elements that were renamed during obfuscation.
We on the Dotfuscator team are always adding new features to improve the protection provided by Dotfuscator, as well as making the configuration process easier. Stay up-to-date with the latest Dotfuscator version by visiting the Dotfuscator Downloads page. For announcements and other information, keep an eye on our blog and follow our Twitter account, @PreEmptive.
Dotfuscator Version 4.33.0.6680. Copyright © 2017 PreEmptive Solutions, LLC