While reading the documents of Eazfuscator.NET i found that it includes two features called Assembly Merging and Assembly Embedding. For the sake of error reporting i created my own library. You can find this library at CodePlex CrashReporter.NET
Anyone can use assembly merging or embedding by following below instructions
Assemblies Merging
Introduction
Assemblies merging allows to merge several assemblies into one. This
may be beneficial from the deployment and security points of view.
Assemblies merging technology uses ILMerge utility underneath. So in
order to use assemblies merging please ensure that ILMerge is
installed on your machine. Assemblies merging is also achievable by
using ILMerge utility separately but at the most cases it's much more
handier to use assemblies merging interface provided by
Eazfuscator.NET.
Benefits from using assemblies merging from Eazfuscator.NET vs. direct
ILMerge usage
Eazfuscator.NET integrates automatically into the project build
process with the help from Eazfuscator.NET Assistant. In case of
direct ILMerge usage, you have to write build event handlers for the
project manually Eazfuscator.NET magically handles signing options of
the project. In case of direct ILMerge usage, you have to supply it
with signing key and options manually Eazfuscator.NET provides
ILMerge with target platform information which is automatically
detected from input assembly. In case of direct ILMerge usage, you
have to supply this information manually Eazfuscator.NET feeds
ILMerge with all required options, so you do not have to read ILMerge
manual. It speeds up integration a lot
By default, assemblies merging is not used during obfuscation of the
assembly.
Instructions
To enable assemblies merging you should apply specially formed
attribute(s) to your assembly. In order to do that you can use the
instructions below.
Instructions on enabling assemblies merging
Open obfuscatable project inside the IDE Add new source file to the
project and call it ObfuscationSettings.cs (for C#) or
ObfuscationSettings.vb (for Visual Basic .NET). You may prefer to use
another name instead of ObfuscationSettings.cs or
ObfuscationSettings.vb Fill ObfuscationSettings.cs with the following
content (C#):
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "merge with XXXXXX.dll", Exclude = false)]
For Visual Basic .NET, fill ObfuscationSettings.vb with the following
content:
Imports System
Imports System.Reflection
<Assembly: Obfuscation(Feature:="merge with XXXXXX.dll", Exclude:=False)>
Note
Change XXXXXX.dll with the file name of the assembly you want to merge
with.
Tip
If you want to merge with several assemblies then just add several
attributes:
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "merge with Assembly1.dll", Exclude = false)]
[assembly: Obfuscation(Feature = "merge with AnotherAssembly2.dll", Exclude = false)]
…
Note Usage of assemblies merging may lead to some side effects which may make obfuscation fail. If such is the case then use the
principle of the least common denominator – merge just those
assemblies which do not cause obfuscation failure. Assemblies
embedding can be used in conjunction or as an alternative to
assemblies merging.
Custom Parameters for ILMerge
Sometimes you may need to pass custom parameters to ILMerge utility.
For example, you may prefer to control class internalization yourself
or use some tricky ILMerge feature. In order to do that you can use
the instructions below.
Instructions on passing custom parameters to ILMerge
Open obfuscatable project inside the IDE Add new source file to the
project and call it ObfuscationSettings.cs (for C#) or
ObfuscationSettings.vb (for Visual Basic .NET). You may prefer to use
another name instead of ObfuscationSettings.cs or
ObfuscationSettings.vb Fill ObfuscationSettings.cs with the following
content (C#):
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "ilmerge custom parameters: <parameters>", Exclude = false)]
For Visual Basic .NET, fill ObfuscationSettings.vb with the following
content:
Imports System
Imports System.Reflection
<Assembly: Obfuscation(Feature:="ilmerge custom parameters: <parameters>", Exclude:=False)>
Note
Change with the parameters you want to pass.
Eazfuscator.NET passes /internalize /ndebug parameters by default when
no attribute defined. If you do not want to pass any parameters to
ILMerge then change with none string.
Assemblies Embedding Instructions
Assemblies Embedding
Introduction
Assemblies embedding allows to embed assembly's dependencies into
assembly itself. This may be beneficial from the deployment and
security points of view.
Assemblies embedding is similar to merging. The main difference is
that the assemblies are not merged into single assembly when they are
embedded. They just get encrypted and packed as the assembly
resources. As a result, there is a single assembly at the output and
it contains the packed dependencies at the same file.
What's the point for embedding when we have merging (or vice versa)?
Assemblies merging delivers the best performance for the resulting
assemblies. They can be NGENed, they work in all constrained
environments (Windows Phone, Compact Framework etc.). File mappings
and JIT'ted code can be cached by the operating system for such
assemblies, bringing the blinding fast application startups. Assembly
merging definitely rocks.
The only downside of merging is that it's not always possible to apply
it without breaking the application. So this is the point where
assemblies embedding comes to the rescue.
Embedded assemblies are easy goals to achieve and they work out of the
box. Downsides? Well, they are present. Embedded assemblies can not be
NGENed, they do not work in some constrained environments (Xbox,
Windows Phone and Compact Framefork). The extraction of embedded
assemblies during the application load is a performance penalty
(penalty is pretty small, so it's unlikely you are able to notice it).
Assemblies embedding brings some benefits as well. The embedded
assemblies are encrypted, so this is a securty hardening against the
hackers. Embedded assemblies are compressed, bringing the size
reduction of the resulting assembly. And of course assemblies
embedding is the easiest way to achieve single-file deployment, making
your application to consist of a single .exe (or .dll) file.
Instructions
To enable assemblies embedding you should apply specially formed
attribute(s) to your assembly. In order to do that you can use the
instructions below. Instructions on enabling assemblies embedding
Open obfuscatable project inside the IDE Add new source file to the
project and call it ObfuscationSettings.cs (for C#) or
ObfuscationSettings.vb (for Visual Basic .NET). You may prefer to use
another name instead of ObfuscationSettings.cs or
ObfuscationSettings.vb Fill ObfuscationSettings.cs with the following
content (C#):
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "embed XXXXXX.dll", Exclude = false)]
For Visual Basic .NET, fill ObfuscationSettings.vb with the following
content:
Imports System
Imports System.Reflection
<Assembly: Obfuscation(Feature:="embed XXXXXX.dll", Exclude:=False)>
Note
Change XXXXXX.dll with the file name of the assembly you want to
embed.
Important
It is recommended to obsuscate the embedded assemblies.
Tip
Eazfuscator.NET automatically finds the assembly path when only the
file name is supplied. If you prefer to specify the exact file path
to assembly then you can use script variables:
[assembly: Obfuscation(Feature = @"embed $(InputDir)\Lib\AssemblyToEmbed.dll", Exclude = false)]
Tip
If you want to embed several assemblies then just add several
attributes:
[assembly: Obfuscation(Feature = "embed Assembly1.dll", Exclude = false)]
[assembly: Obfuscation(Feature = "embed AnotherAssembly2.dll", Exclude = false)]
…
Tuning
Embedded assemblies are compressed and encrypted by default. You may
prefer to turn off the compression, encryption or them both. In order
to do that, please read the notes below.
The full notation of a custom attribute for assembly embedding has the
following form:
[assembly: Obfuscation(Feature = "embed [flags] XXXXXX.dll", Exclude = false)]
where [flags] is an optional enumeration of flags separated by spaces.
The list of available flags is presented in the table below.
Below is the list of flags for assembly embedding attribute
Flag Description no_compress Disables the compression no_encrypt
Disables the encryption no_satellites Disables automatic embedding of
satellite assemblies load_from_file Instructs Eazfuscator.NET to load
the embedded assembly from file instead of memory during the
obfuscated assembly run-time. This can be used to preserve a
meaningful value of Location property from System.Reflection.Assembly
type.
Let's take a look on examples.
Example 4.24. Embed assembly without compression and encryption
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "embed [no_compress no_encrypt] XXXXXX.dll", Exclude = false)]
Example 4.25. Embed assembly without encryption; compression is
enabled
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "embed [no_encrypt] XXXXXX.dll", Exclude = false)]
Example 4.26. Embed assembly; compression and encryption are enabled
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "embed XXXXXX.dll", Exclude = false)]
Example 4.27. Embed own satellite assemblies; compression and
encryption are enabled
using System;
using System.Reflection;
[assembly: Obfuscation(Feature = "embed satellites", Exclude = false)]
Troubleshooting While assembly embedding is the most non-intrusive way to link the assembly, some rare issues may occur. Possible issues
are described in this chapter together with corresponding solutions to
avoid them. Location property of System.Reflection.Assembly class
Issue summary. Location property of System.Reflection.Assembly class
is often used to find the paths of files near the assembly. While not
being a correct solution, this works for most deployment scenarios.
What may go wrong? First of all, Location property can have a
completely unexpected value when assembly shadow copying is used, thus
breaking the intended application logic. Secondly, Location property
has a null value when a corresponding assembly is embedded.
Solution. Use EscapedCodeBase property instead. This property always
has a correct value in all deployment scenarios. Please take a look at
the sample below.
using System;
class Program
{
static string GetEulaPath()
{
var assembly = typeof(Program).Assembly;
// string location = assembly.Location; // Please do not use this. This is a flawed approach
string location = new Uri(assembly.EscapedCodeBase).LocalPath; // <-- Use this instead
return Path.Combine(Path.GetDirectoryName(location), "EULA.rtf");
}
}