You are on page 1of 177

1

Babel
Obfuscator
User’s Guide

Version 9.3.3.0
2

Babel Obfuscator User’s Guide

Manual Version 9.3.3.0


http://www.babelfor.net/

babelfor.NET
Copyright © 2011-2020 babelfor.NET. All rights reserved.

Trademarks

.NETTM , MSILTM, and Visual Studio .NETTM are trademarks of Microsoft, Inc.
All other trademarks are the property of their respective owners.

Warning and Disclaimer

Every effort has been made to make this manual as complete and accurate as possible, but no warranty or
fitness is implied. The information provided is on an “as is” basis. The author shall have neither liability nor
responsibility to any person or entity with respect to any loss or damages arising from the information
contained in this manual.
3
4

Table of Contents

Babel Obfuscator .......................................................................................................................................................... 1


User’s Guide ................................................................................................................................................................. 1
Trademarks ....................................................................................................................................................................... 2
Warning and Disclaimer ................................................................................................................................................... 2
Table of Contents ............................................................................................................................................................. 4
Conventions Used in This Manual .................................................................................................................................. 12
Introduction ................................................................................................................................................................13
Obfuscation at a Glance ................................................................................................................................................. 13
Benefits of Babel Obfuscator.......................................................................................................................................... 13
Software Requirements.................................................................................................................................................. 14
What’s New .................................................................................................................................................................... 15
Babel Obfuscator Release Notes .................................................................................................................................... 15
Assembly version 9.3.3.0, File version 9.3.3.0 ........................................................................................................... 15
Babel Obfuscator .........................................................................................................................................................16
Product Features ............................................................................................................................................................ 17
General Features ........................................................................................................................................................ 17
Obfuscation ................................................................................................................................................................ 17
Code Protection ......................................................................................................................................................... 17
Code Instrumentation and Optimization ................................................................................................................... 17
Deployment................................................................................................................................................................ 18
Feature Matrix ................................................................................................................................................................ 19
Technology Matrix .......................................................................................................................................................... 21
Available Licensing Models ..........................................................................................................................................23
Single-User Licenses ....................................................................................................................................................... 23
Standard License ........................................................................................................................................................ 23
Professional License ................................................................................................................................................... 23
Enterprise License ...................................................................................................................................................... 24
Multi-User License .......................................................................................................................................................... 24
Company License ....................................................................................................................................................... 25
Additional Benefits ......................................................................................................................................................... 25
End User License Agreement.......................................................................................................................................... 25
Licensing FAQ ................................................................................................................................................................. 26
License File ..................................................................................................................................................................... 27
Troubleshooting License File Issues ........................................................................................................................... 27
5

Babel Obfuscator Version History .................................................................................................................................. 28


Latest Babel Obfuscator Commercial Version ................................................................................................................ 28
The Free Babel Obfuscator Version 2.0.0.1 .................................................................................................................... 28
Overview ........................................................................................................................................................................ 29
Using Babel Obfuscator ...............................................................................................................................................30
Setup Babel on Windows ............................................................................................................................................... 31
Setup Babel for Mono on MAC OSX ............................................................................................................................... 32
Setup Babel dotnet CLI Tools on Linux and MAC OSX .................................................................................................... 33
Configure NuGet ........................................................................................................................................................ 33
Install the Tools .......................................................................................................................................................... 33
Setup the License File................................................................................................................................................. 34
Babel Obfuscator User Interface .................................................................................................................................... 35
Creating a New Solution File ...................................................................................................................................... 36
Changing Obfuscation Settings .................................................................................................................................. 38
Code Generation Options .......................................................................................................................................... 38
Setting the Output and Building the Project .............................................................................................................. 39
Examine the Obfuscated Assemblies ......................................................................................................................... 41
Deobfuscating Stack Trace ......................................................................................................................................... 42
Command Line Tool .....................................................................................................................................................44
Miscellaneous ................................................................................................................................................................. 45
--help [option] (?) ....................................................................................................................................................... 45
--[no]logo (enabled) ............................................................................................................................................. 45
--license [path] ........................................................................................................................................................... 45
--verbose <n> (v) ........................................................................................................................................................ 45
--noconfig (@) (disabled) ........................................................................................................................................ 45
--nowarn <warn list> .................................................................................................................................................. 46
--[no]warnaserror [warn list] ..................................................................................................................................... 46
--[no]statistics (enabled) ........................................................................................................................................ 46
--[no]agent (a) (enabled) ........................................................................................................................................ 46
--[no]satellite [assembly] ........................................................................................................................................... 46
--addsearch <path> .................................................................................................................................................... 46
--take <regex> ............................................................................................................................................................ 46
--skip <regex> ............................................................................................................................................................. 47
--compress <n> (6) .................................................................................................................................................. 47
--quickrule <rule> ....................................................................................................................................................... 47
--[no]removekey ........................................................................................................................................................ 48
6

--dbghelpdlldir <path> ............................................................................................................................................... 48


--trace <regex> ........................................................................................................................................................... 48
--randomseed <seed> ................................................................................................................................................ 48
--use <key=value> ...................................................................................................................................................... 48
--detectifobfuscated [action] ..................................................................................................................................... 48
Plugins ............................................................................................................................................................................ 48
--plugin <file> ............................................................................................................................................................. 48
--argument <key=value> ............................................................................................................................................ 49
Merge and Embed Assemblies ....................................................................................................................................... 49
--[no]internalize (disabled) .................................................................................................................................... 49
--[no]copyattrs [regex] (enabled) ........................................................................................................................... 49
--embed <assembly> .................................................................................................................................................. 49
Renaming........................................................................................................................................................................ 49
--[no]types (t) (enabled) ......................................................................................................................................... 49
--[no]events (e) (enabled)....................................................................................................................................... 49
--[no]methods (m) (enabled) .................................................................................................................................. 49
--[no]parameters (r) (enabled) ............................................................................................................................... 49
--[no]properties (p) (enabled) ................................................................................................................................ 50
--[no]fields (f) (enabled) ......................................................................................................................................... 50
--[no]xaml (x) (disabled) ......................................................................................................................................... 50
--[no]virtual (enabled) ............................................................................................................................................ 50
--[no]overloaded (disabled) .................................................................................................................................... 50
--[no]flatns (n) (enabled) ........................................................................................................................................ 50
--[no]unicode [char set] (enabled) ......................................................................................................................... 50
--namelength <n> (1) .............................................................................................................................................. 50
--nameprefix [prefix] .................................................................................................................................................. 51
--[no]xmldoc [file|regex] (enabled) ........................................................................................................................ 51
Control Flow Obfuscation ............................................................................................................................................... 51
--[no]controlflow (enabled) .................................................................................................................................... 51
--iliterations <n> ......................................................................................................................................................... 52
--[no]invalidopcodes [mode] (disabled) ................................................................................................................. 52
Encryption and Protection.............................................................................................................................................. 52
--[no]msilencryption [regex] (disabled) .................................................................................................................. 52
--[no]stringencryption [name] (enabled)................................................................................................................ 52
--[no]valueencryption [key=value] (disabled) ........................................................................................................ 52
--[no]ildasm (enabled) ............................................................................................................................................ 53
7

--[no]reflection (enabled) ....................................................................................................................................... 53


--[no]resourceencryption (disabled)....................................................................................................................... 53
--[no]proxy [type][;regex] (disabled) ...................................................................................................................... 53
--[no]tamperingdetection (disabled) ...................................................................................................................... 53
--[no]antidebugging (disabled) ............................................................................................................................... 53
Code Generation ............................................................................................................................................................ 54
--addreference <assembly> ....................................................................................................................................... 54
--[no]instrument [regex] (disabled) ....................................................................................................................... 54
--[no]emptymethods (enabled) .............................................................................................................................. 54
--[no]deadcode [regex] (disabled) .......................................................................................................................... 54
--[no]seal (disabled) ............................................................................................................................................ 54
--[no]cleanattrs <regex> (disabled) ........................................................................................................................ 54
--[no]enumremoval (disabled)................................................................................................................................ 54
--[no]constremoval (disabled) ................................................................................................................................ 54
--[no]disgregateremoval (disabled) ........................................................................................................................ 55
--[no]inlineexpansion (disabled) ........................................................................................................................... 55
--moduleinitializer [method] ...................................................................................................................................... 55
--[no]debug [source] (disabled) .............................................................................................................................. 55
Output Files .................................................................................................................................................................... 56
--output <file> ............................................................................................................................................................ 56
--pdb <file> ................................................................................................................................................................. 56
--pdbpwd <password> ............................................................................................................................................... 56
--logfile <file> ............................................................................................................................................................. 56
--mapout [file] ............................................................................................................................................................ 56
--makeproject [file] .................................................................................................................................................... 56
Input Files ....................................................................................................................................................................... 56
--keyfile <file>............................................................................................................................................................. 56
--keyname <container> .............................................................................................................................................. 56
--keypwd <password> ................................................................................................................................................ 57
--keystore <file> ......................................................................................................................................................... 57
--keypass <password> ................................................................................................................................................ 57
--keyalias <alias> ........................................................................................................................................................ 57
--storepass <password> ............................................................................................................................................. 57
--rules <file> ............................................................................................................................................................... 57
--mapin <file> ............................................................................................................................................................. 57
--project <file> ............................................................................................................................................................ 57
8

--stacktrace <file>....................................................................................................................................................... 57
Configuration File ........................................................................................................................................................... 58
Processing Phases........................................................................................................................................................... 61
Obfuscation Agent .......................................................................................................................................................... 62
Obfuscation Rules........................................................................................................................................................64
Rules Files ....................................................................................................................................................................... 64
Rules Element ............................................................................................................................................................ 64
Rule Element .............................................................................................................................................................. 64
Custom Attributes .......................................................................................................................................................... 71
The ObfuscateAssembly Attribute ................................................................................................................................. 71
The Obfuscation Attribute .............................................................................................................................................. 71
Edit Rules ........................................................................................................................................................................ 73
Merge and Embed .......................................................................................................................................................75
Assembly Merging .......................................................................................................................................................... 76
Merging Silverlight and WPF assemblies ........................................................................................................................ 77
Assembly Embedding ..................................................................................................................................................... 78
Symbols Renaming ......................................................................................................................................................80
Symbols Renaming ......................................................................................................................................................... 81
Unicode Character Set .................................................................................................................................................... 83
Overloaded Renaming .................................................................................................................................................... 83
XAML and BAML Obfuscation ........................................................................................................................................ 84
Advanced XAML Settings ........................................................................................................................................... 84
Silverlight XAML Obfuscation ......................................................................................................................................... 85
Control Flow Obfuscation ............................................................................................................................................87
Basic Control Flow Obfuscation...................................................................................................................................... 88
Enhanced Control Flow Obfuscation .............................................................................................................................. 89
Invalid Op-Codes ............................................................................................................................................................ 90
Encryption and Protection ...........................................................................................................................................92
Code Encryption ............................................................................................................................................................. 93
String Encryption ............................................................................................................................................................ 96
XOR Algorithm............................................................................................................................................................ 96
HASH Algorithm ......................................................................................................................................................... 96
Custom String Encryption ............................................................................................................................................... 97
Inline Values and Array Encryption ................................................................................................................................ 97
Resource Encryption....................................................................................................................................................... 99
Dynamic Proxy Calls...................................................................................................................................................... 101
9

Tampering Detection .................................................................................................................................................... 102


Debugging Protection ................................................................................................................................................... 103
Code Generation ....................................................................................................................................................... 104
Dead Code Removal ..................................................................................................................................................... 105
Metadata Optimizations............................................................................................................................................... 105
Automatic Class Sealing ........................................................................................................................................... 105
Removing of Unwanted Attributes .......................................................................................................................... 106
System.Enum Types Removal .................................................................................................................................. 107
Disgregate Removal ................................................................................................................................................. 108
Code Optimizations ...................................................................................................................................................... 108
Inline Expansion ....................................................................................................................................................... 108
Code Instrumentation ............................................................................................................................................... 110
Activating Instrumentation ........................................................................................................................................ 111
Simple Tracing Walkthrough ........................................................................................................................................ 112
Creating SimpleTrace Project ................................................................................................................................... 112
Adding stub methods and building the project ....................................................................................................... 114
Creating an Obfuscation Test Project ...................................................................................................................... 114
Instrumenting the TestClient Application ................................................................................................................ 115
MSBuild Task ............................................................................................................................................................. 117
MSBuild Babel Task ...................................................................................................................................................... 118
Babel MSBuild Project Files .......................................................................................................................................... 121
Task Attributes ............................................................................................................................................................. 123
Using Babel Task in Visual Studio ................................................................................................................................. 130
Using Babel Task in Xamarin Studio ............................................................................................................................. 131
Visual Studio Build ..................................................................................................................................................... 134
Post Build Event ............................................................................................................................................................ 135
Visual Studio Project File .............................................................................................................................................. 135
Add an XML Rule File in Visual Studio Project .............................................................................................................. 136
Enable Obfuscation on Release Build ........................................................................................................................... 136
Setup Obfuscation for Silverlight.................................................................................................................................. 137
Setup Obfuscation for ClickOnce .................................................................................................................................. 137
Setup Obfuscation for Windows Store ......................................................................................................................... 138
Setup Obfuscation for .NET Micro Framework and nanoFramework .......................................................................... 139
.NET Micro Framework ............................................................................................................................................ 139
nanoFramework ....................................................................................................................................................... 139
Setup Obfuscation for Windows Phone ....................................................................................................................... 140
10

Setup Obfuscation for Xamarin Forms ......................................................................................................................... 141


Babel Obfuscation of Xamarin.Forms solution for Android and iOS ........................................................................ 141
Merging Babel Licensing .......................................................................................................................................... 142
Babel Obfuscation in Visual Studio 2017 for Mac .................................................................................................... 142
Customizing Intellisense ............................................................................................................................................... 144
Babel NuGet Package ................................................................................................................................................ 145
Running Babel Obfuscator in Visual Studio .................................................................................................................. 146
Customize the Obfuscation ...................................................................................................................................... 148
Setting Up a Common License File ........................................................................................................................... 148
Adding Obfuscation Rules Files ................................................................................................................................ 148
Merge and Embed Assemblies ................................................................................................................................. 149
Mapping Files ........................................................................................................................................................... 149
Optimizations ........................................................................................................................................................... 149
Babel Plugins ............................................................................................................................................................ 150
DevOps Integration ...................................................................................................................................................... 150
Create License Files in DevOps ..................................................................................................................................... 151
Handling Packages ..................................................................................................................................................... 152
XAP Packages ................................................................................................................................................................ 153
XAP Package Compression ....................................................................................................................................... 153
XAP Skip List ............................................................................................................................................................. 153
APPX Packages .............................................................................................................................................................. 154
APPX Package Signing .............................................................................................................................................. 154
Android APK Packages .................................................................................................................................................. 155
Cross Assembly Obfuscation with Packages................................................................................................................. 155
Advanced Topics ........................................................................................................................................................ 156
Satellite Assemblies for Localized Applications ............................................................................................................ 157
PFX Assembly Signing ................................................................................................................................................... 158
Obfuscating x64 Assemblies ......................................................................................................................................... 159
Customize MSIL Encryption .......................................................................................................................................... 159
Cross Assembly Obfuscation ........................................................................................................................................ 160
Setup from The User Interface ................................................................................................................................. 162
Babel Obfuscator Plugins ............................................................................................................................................. 163
Code Samples ........................................................................................................................................................... 163
Custom String Encryption ........................................................................................................................................ 164
Custom Value Encryption ......................................................................................................................................... 164
Merging Code ........................................................................................................................................................... 165
11

Loading Plugins ........................................................................................................................................................ 167


Using Plugins in Babel Task ...................................................................................................................................... 169
Debugging a Plugin................................................................................................................................................... 170
Obfuscation Guidelines ............................................................................................................................................. 171
Troubleshooting a Broken Application ......................................................................................................................... 172
Appendix A ................................................................................................................................................................ 173
Warning Codes ............................................................................................................................................................. 173
Unicode Character Ranges ........................................................................................................................................... 175
Index ......................................................................................................................................................................... 176
12

Conventions Used in This Manual

Various typefaces in this manual identify terms and other special items.
These typefaces include the following:

Typeface Meaning
Italic Italic is used for new terms or phrases when they are initially defined and occasionally
for emphasis.
Monospace Monospace is used for screen messages, code listings, command
samples, and filenames.
Code listings are colorized similarly to Visual Studio. Blue monospace type is used
for XML elements and C# keywords. Brown monospace type is used for XML element
names and C# strings. Green monospace type is used for comments. Red
monospace type is used for XML attributes. Teal monospace type is used for C# type
names.
13

Introduction
Thank you for choosing Babel Obfuscator for the .NET Framework. This manual will guide you using the
numerous features of this obfuscator. Babel was made with the goal of being easy to use and at the same
time deliver powerful obfuscation features.

Obfuscation at a Glance

Obfuscation is a transformation process in which the code is changed to make it unclear and difficult to
understand, so that reversing is more difficult. Software written in .NET languages like C# and Visual Basic
are usually easy to reverse engineer because they compile to MSIL (Microsoft Intermediate Language), a
CPU- independent instruction set that is embedded into .NET assemblies, along with other information
(Metadata). This enables decompilation back to the original source code.

There are plenty of tools available online that enable the decompilation of .NET binaries into high-level
languages. The most popular are .NET Reflector and IDA. And the Microsoft .NET Framework SDK provides
ILDASM, a tool to disassemble .NET binaries to MSIL, making reverse engineering extremely easy. Since
MSIL is CPU independent, .NET assemblies can run on any platform that implements the CLR (Common
Language Runtime)—a software infrastructure necessary to execute .NET binaries. The drawback is that
software companies and IT professionals cannot protect their intellectual property if their software can be
decompiled.

Benefits of Babel Obfuscator

Babel Obfuscator is a tool for the .NET Framework to transform assemblies in order to conceal the code and
make reverse engineering difficult. The completely managed solution of MSIL Encryption ensures that the
code of the method is no longer accessible using the disassemblers available on the market. MSIL encryption
can be configured to strip code from the assembly and serialize it to encrypted files that can be loaded at
runtime from safe stores or license files. This method permits the deployment of your software with a reduced
set of features in the primary binaries in which the functionality can be activated only by access to the safe
store.

Babel also performs user string encryption and control flow obfuscation, hiding all the information that can be
used by reversers to identify and break software protection routines.

Symbol overload renaming reduces the resulting metadata size, which also reduces the overall size of the
obfuscated assembly and improves executable load time.

The integration with MSBuild enables Babel to be used in automated build environments, and thus
significantly reduces the time required to deliver the final product to testing and deployment.

Important note: A lot of effort was invested to ensure that the transformations performed by Babel are safe,
and the resulting software functionalities are not affected. Since obfuscation processes involve complex MSIL
changes, occasionally the obfuscated assembly could be compromised. To avoid this possibility the
obfuscated software should be thoroughly tested before deploying to the end users.
14

Software Requirements

The following software is required:

 A version of Windows that supports the .NET Framework 4.7.2 This can be Windows 10,
Windows Server 2012 R2, Windows 7 SP1, Windows 8.1

You can read more about .NET 4.7.2 system requirements at:
https://docs.microsoft.com/en-us/dotnet/framework/get-started/system-requirements

 .NET Framework 4.7.2


 The Windows Software Development Kit (SDK), specifically the .NET tools it includes. This is a
free download from http://msdn.com.

In addition, the following software is recommended:

 Visual Studio 2008 or later; an alternative free Express edition can be downloaded from
http://msdn.com
15

What’s New

• Bug fixes (see Release Notes Bug Fixes)

Babel Obfuscator Release Notes

Assembly version 9.3.3.0, File version 9.3.3.0

Bug Fixes

• Fix: The JSON dependency manifest is not updated when embedding .NET Core assemblies.
• Fix: XML license validation could raise the error: XML document not loaded.
• Fix: PInvoke adds .DLL extension to non-windows library imports
• Fix: Stability issue that will make obfuscated assemblies to crash with error:
System.TypeInitializationException: The type initializer for '?' threw an exception.
This fix affects the following encryption features:
Code Encryption
String Encryption HASH, XOR
Value Encryption
Resource Encryption
• Fix: A XAML parsing issue that in some occasions could raise the warning
W00002: Cannot parse BAML resource stream
• Fix: Dynamic Proxy Call could generate the following error:
System.TypeInitializationException: The type initializer for 'xyz' threw an exception.
System.NotSupportedException: The return Type contains some invalid type
• Fix: XML rules targeting methods, fields, properties or events do not match if any
HasAttribute has been defined

The release notes for past releases are available at the following address
http://www.babelfor.net/releasenotes
16

Babel Obfuscator
Babel Obfuscator is a powerful tool with many features available in three different editions: Standard,
Professional, Enterprise and Company to accommodate an increasing number of features and prices.
This section shows the differences between the various editions of Babel Obfuscator.
17

Product Features

The main features are listed below:

General Features

 Works with Microsoft .NET Framework 1.1, 2.0, 3.5, 4.0, 4.5, 4.x, .NET Core 2.x, 3.0, .NET
Standard 2.x, Windows Runtime and Windows Store applications, .NET Nano Framework, .NET
Micro Framework 3.0, 4.x, Silverlight 3.0 to 5.0, Compact Framework, Windows Phone 7.x/8,
Xbox 360 XNA Framework 2.0, 3.0, 4.x, Xamarin Mono for Android and iOS, MonoGame, Unity3D
 Supports obfuscation of mixed-mode assemblies
 Selective Obfuscation with XML Rule Files
 XML Mapping Files
 Declarative Obfuscation using Custom Attributes
 Graphic User Interface
 Visual Studio Post-Build Integration
 MSBuild and DevOps Integration
 Supports Command Line Interface
 Supports Multiprocessor Execution
 Disables tools like .NET Reflector, Reflexil plug-in, and ILDASM
 One year of free product updates
 Custom plugins

Obfuscation

 XAML and BAML Obfuscation


 Obfuscates Namespaces, Types, Methods, Events, Properties and Fields
 Unicode Normalization and Custom Character Set
 Includes Generic Types and Virtual Function Obfuscation
 Public Members Obfuscation
 Supports Incremental Renaming

Code Protection

 Dynamic Proxy Calls to External and Internal Methods


 MSIL Control Flow Obfuscation
 String Encryption
 Inline Values and Arrays Encryption
 MSIL Encryption
 Embedded Resources Encryption
 Tampering Detection
 Debugging Protection

Code Instrumentation and Optimization

 Code Instrumentation
 Dead Code Removal
 Automatic Class Sealing
 Attributes Cleanup
 System.Enum Type Removal
 Constant Fields Removal
18

Deployment

 Assembly Merging
 Assembly Embedding
 Supports Silverlight XAP Packages
 Supports Windows Store APPX Packages
 Supports Android APK Packages
 Automatic Obfuscation of Satellite Assemblies
 Automatic Management of XML document files
 Supports re-sign with PFX and Strong Name Signature
 Supports decoding of obfuscated stack
19

Feature Matrix

Babel is available in 3 editions: Standard, Professional and Enterprise. The following table shows the features
included in each edition.

Enterprise
Features Standard Professional
Company
.NET Framework Support
Microsoft .NET Framework from 1.1 to 4.8.x, .NET
Core 3.0, 2.x, .NET Standard 2.x, Silverlight from
3.0 to 5.0, Compact Framework, .NET Nano
Framework, .NET Micro Framework 3.0, 4.x,
Windows Phone 7.x/8, Xbox 360 XNA Framework
from 2.0 to 4.5, Windows Runtime, Xamarin Android
and iOS, MonoGame, Unity 3D
Tools Can Run on .NET Core 3.0 Build (Linux
Company
Ubuntu, Mac OSX)
64 Bit Support
Supports obfuscation of Windows Store APPX
Packages, Android APK Packages and Silverlight
XAP Packages
Mixed Mode Assemblies
Custom Plugins
Obfuscation
Symbol Renaming
Generic Types and Methods
XML Rule Files
Unicode Normalization
Overload Renaming
Custom Character Set Obfuscation
Public Symbol Obfuscation
XAML and BAML Obfuscation
Code Protection
Control Flow Obfuscation
Invalid Op-Codes 1
Prevent ILDasm1
String Encryption1
Inline Values and Arrays Encryption
Protection Against Reflection
Dynamic Proxy Calls (Internal/External Methods)
Resource Encryption1
MSIL Encryption1
Tampering Detection
Debugging Protection
Code Instrumentation and Optimization
Dead Code Removal
Automatic Class Sealing and Attributes Cleanup

1 Refer to Technology Matrix to see .NET Framework compatibility.


20

System.Enum Type Removal


Constant Fields Removal
Disgregate Removal
Inline Expansion
Code Instrumentation
Deployment
Strong Name Signature with SNK
XML Map Files Generation
Supports XML Documentation Files
Debug PDB File Generation
Supports Resign with PFX Files
Assembly Embedding
Satellite Assemblies
Assembly Merging (WPF and Silverlight included)
Tools Integration
Command Line Interface
Visual Studio Post Build Events
MSBuild and NAnt Support
Parallel Phase Execution
DevOps Build Integration Company
Product Services
One Year of Product Upgrades
Multi-User License Company
21

Technology Matrix

This table shows the availability of Babel Obfuscator features in relation to different .NET Framework version
and technologies.

Compact Framework
.NET Framework 4.x

.NET Framework 1.1

Mono Android / iOS


.NET Micro & Nano

Windows Runtime
XNA 4.0 XBOX360
.NET Core 2.0 3.0
Edition PRO/ENT

(Xamarin Forms)
.NET Framework

Windows Phone
Framework

Silverlight
2.0 3.x
Obfuscation
STD Symbol Renaming
STD Generic Types and Methods
STD XML Rule Files
PRO Unicode/Custom Characters
PRO Overload Renaming
PRO Mixed Mode Assemblies
ENT XAML and BAML Obfuscation
Code Protection
STD Invalid Op-Codes
STD Prevent ILDasm
PRO Control Flow Obfuscation
PRO String Encryption
PRO Encrypt Values and Arrays
PRO Anti-Reflection Protection
PRO Dynamic Proxy Calls
PRO Resource Encryption
ENT MSIL Encryption 3.0

ENT Tampering Detection


ENT Debugging Protection
Code Optimization
PRO Dead Code
PRO
Automatic Class Sealing,
Attribute Cleanup
ENT Code Instrumentation
System.Enum Type Removal,
ENT
Const Fields Removal,
Disgregate Removal, Inline
Expansion
Deployment
STD Strong Name Signature
STD XML Map Files Generation
PRO Resign with PFX Files
PRO APPX, APK, XAP Packages
PRO Assembly Embedding
22

ENT Satellite Assemblies


ENT Assembly Merging
23

Available Licensing
Models
Babel Obfuscator and Licensing can be downloaded and installed for free. The product without a license file
works in demo mode. In this mode, the obfuscated assemblies will stop to work after 15 days from their
generation. All advanced obfuscation features like enhanced string encryption and control flow obfuscation
are not available in the product demo. To unlock the time expiration and enjoy the advanced obfuscation
features you must purchase a license.

There are no other restrictions or royalty fees for applications obfuscated with Babel Obfuscator and
Licensing. With each license, you receive 12 months of free updates from the date of purchase – be it a minor
service update or a major new version. After the 12-month period and at your discretion, you can pay about
40% of original price to "renew" the subscription and receive another 12 months of free updates. If you choose
not to renew, you can continue using the last version you obtained or are eligible to use. The 12-month time
frame is merely for new versions/updates and has no relevance to rights of use.

Single-User Licenses

Single user licenses are

 Standard
 Professional
 Enterprise

You can install Babel Obfuscator on your machine(s) for your single use only. This means that a license must
be purchased for each developer that uses Babel Obfuscator.

Standard License
The Standard single-user license, allows you to own basic obfuscation features:

 Automatic Handling of Silverlight XAP Packages


 Custom Unicode Character Set Obfuscation
 Advanced String Encryption
 XML Configuration Rules
 Debug PDB Symbol File Support
 Resign with Strong Name Keys (SNK files)
 Debug PDB File Support
 Control Flow Obfuscation
 Support for Visual Studio, MSBuild, NAnt and Command Line
 Graphic User Interface

The support for MSBuild, NAnt and Microsoft Visual Studio as well as selective obfuscation with XML rules
files, is included in all product licenses.

Professional License
The Professional single-user license includes most of the advanced protection features available with Babel:
24

 Overloaded Renaming
 Dynamic Proxy Calls
 Values and Arrays Encryption

It also provides most of the code optimizations and deployment facilities such as:

 Dead Code Removal


 Automatic Class Sealing
 Assembly Embedding
 Support Resign with Personal Information Exchange (PFX) files

With these features, you will be able to effectively obfuscate your assemblies, simplify and reduce the size of
deployed assembly removing not used code and embedding your references.

Enterprise License
The Enterprise single-user license is one that enables all the advanced features of the product. You will have,
over the features of the Professional license, also the MSIL code encryption and the possibility to obfuscate
the members used in the XAML and BAML code. Plus, you will have the encryption of embedded resources
and more optimizations and deployment features including assembly merging and System.Enum type
removal. With assembly merging you will be able to merge all the dependencies into the main assembly,
improving the obfuscation of the deployed application.

Here are the features available only with the Enterprise edition:

General Features

 Custom Plugins

Obfuscation

 XAML and BAML obfuscation

Protection

 MSIL encryption
 Embedded resource encryption
 Anti-Tampering Protection

Optimization and Code Instrumentation

 System.Enum type removal


 Constant fields removal
 Code Instrumentation

Deployment

 Assembly merging (WPF and Silverlight included)


 Automatic handling of satellite assemblies

Multi-User License

The multi-user license is the Company license.

 Company
25

This license is suited for companies with many developers who want to use Babel Obfuscator without any
limitation to the number of users who need to access the obfuscation facilities. With the Company license, you
can install Babel Obfuscator on an unlimited number of machines and build servers within your company.

Company License
The Company license is the only one being multi-user, that means that you can license all the developers in
your team purchasing only one Company license.

The Company license beside being multi-user, is the only one to provide Babel Licensing Components and
additional features not available in any single-user edition of Babel Obfuscator:

1) Licensing Components. Or licensing components will allow you to manage digitally signed XML file
licenses or serials. The programmatic interface of Babel Licensing can be integrated in any .NET
application giving the possibility to extend your
2) Licensing Database. Manage products, customers, orders, licenses for your .NET applications.
3) Babel tools for .NET Core. Company license includes Babel tools for .NET Core 3. This means that
you can adopt DevOps as your build solution and integrate babel obfuscator in DevOps or any build
system supporting .NET Core 3. The tools are distributed as a NuGet package available to download
only to Company license subscribers.
4) Babel Encrypt plugin. This plugin brings string encryption to next level. See what Babel Encrypt can
do.
5) Priority Support. This means that you can request a patch for an issue you have found, and we will
provide this before the official release will come out.

If you are interested in our Babel Licensing components, you can know more about the product features at:
http://www.babelfor.net/products/licensing

A demo version of Babel Licensing Component can be installed directly from NuGet:
https://www.nuget.org/packages/Babel.Licensing/
This demo version will allow you to generate and validate software licenses with a fixed limited trial time.

There are several licensing example projects installed with Babel Obfuscator under:
C:\Users\Public\Documents\Babel\Licensing\Samples\Licensing Samples.sln

And an online help library for Babel Licensing programmatic interface, available at:
http://www.babelfor.net/licensing/help

If you need more information about Babel Obfuscator and Licensing feel free to write at sales@babelfor.net

Additional Benefits

With all the editions, you are entitled to have one year of free product updates. Minor and Major release
included. After one year, you can renew your subscription and continue to receive new product releases.
Company licenses will benefit priority email support.

End User License Agreement

The usage of the software is subordinate to the acceptance of our End User License Agreement which can be
read at:

http://www.babelfor.net/products/eula
26

Licensing FAQ

Is your license on a per-developer basis?


Yes, for Standard, Professional and Enterprise licenses. Each developer must obtain a license. With this
license, the developer can install on a primary machine and a portable/laptop. With Company license there
are no limit to the number of developers/machines inside your Company where you can distribute the product.

Do I have to pay you royalties?


No. babelfor.NET does not charge any royalties for redistribution of components obfuscated with Babel
Obfuscator.

Can I install the product on the build server?


Yes. You can install the product in your build server and use your license if you are the only user that have
access to the build. You need to purchase the Company license if:

• You have more than one developer accessing to the build server
• You want to use Babel Obfuscator on DevOps or any other Continue Integration environment

Can I install the product on 2 machines (I'm running a desktop in the office, have a laptop at home)?
Yes.

Can I continue to use Babel Obfuscator if the subscription expires and I choose not to renew?
Yes. You can continue to use Babel Obfuscator which you have licensed and paid for as long as you require.
When a subscription expires, it simply means that you will no longer be issued any product updates or new
product releases.
An expired subscription can be renewed at any time. Feel free to contact our client services for more
information on renewals and product costs once your subscription expires.
27

License File

After purchasing Babel Obfuscator and Licensing, you received the links to download the retail version of
Babel Obfuscator and the babel.license license file. This file needs to be copied into the Babel installation root
folder; usually “C:\Program Files\Babel” and it enable the features that are associated with the edition
purchased. The license file itself is an XML file digitally signed and encloses information about the product,
customer details and other encrypted data specific to the license purchased.

You can access your license information by typing into a DOS shell:

babel.exe –license

If a valid license is not found the following message will be displayed:

Error: A valid babel license could not be found. Please contact http://www.babelfor.net
for assistance.

Note that any modification to the XML license file will invalidate the license itself. Also, if you own a trial or
beta license that has an expiration date, do not run Babel after setting back the computer system time or your
license will be automatically invalidated.

Troubleshooting License File Issues


If you have license file issues, please check out the following points.

1) Ensure the license file babel.licenses is inside the Babel install folder. Typically, the install folder
under Windows OS is C:\Program Files\Babel. If you installed babel in another location, please copy
the license file inside the same folder of babel.exe.
2) Ensure you installed the retail version of Babel Obfuscator. The DEMO version of Babel Obfuscator
available to download at babelfor.net is not suited to run with a retail license. In case you have
installed the DEMO version, please uninstall it before installing the retail version of the product.
3) The babel.licenses license file should be the exact one you received with the Babel setup. Each
version of Babel Obfuscator comes with its license file, and a license file is made for one specific
version of the product and cannot be used with a different product version.

If you are not sure about the license file version, please open the babel.licenses file in a text editor and check
the version inside the <Assembly> element for the tool installed.

<License Id="licEFD9081B">
<Assembly name="babel" version="9.3.3.0" culture="neutral"
publicKeyToken="138d17b5bd621ab7" />
<Assembly name="lic" version="2.8.4.0" culture="neutral"
publicKeyToken="138d17b5bd621ab7" />

The babel tool version can be displayed with the following command:

babel --version

Assembly version: 9.3.3.0


Product version: 9.3.3.0
File version: 9.3.3.0

The version in the license file and the tool assembly version must be the same.
28

Babel Obfuscator Version History

Babel Obfuscator was available for free until release 2.0.0.1.


In the release version 3.0.0.0, has been introduced some major improvements and the product was made
available under a commercial license.

The main differences between the commercial and the free version are listed below:

Latest Babel Obfuscator Commercial Version

 Support all .NET Framework versions from 1.1  Inline Value and Array
to 4.x, .NET Core 3.0, 2.x, .NET Standard 2.x, Encryption
Windows Runtime, Silverlight 3.0 to 5.0,  Automatic Class Sealing
Windows Phone 7.x, Xbox 360 XNA Framework,  Tampering Detection
.NET nanoFramework and .NET Micro  Attributes Removal
Framework 3.0, 4.x, Windows Runtime,  Code and Metadata
Xamarin, Mixed Mode Assemblies optimizations
 Supports all OS running .NET Core 3 (Windows,  Multiprocessor Execution
MAC OSX and Linux)  Performance Improvements
 Graphic user interface  Major Fixes on Symbol
 Supports major build systems like MSBuid and Renaming and Metadata
DevOps Verification
 Compatible with FIPS standards  Log File Output
 Full symbols renaming  PDB File generation
 Incremental Renaming  Custom Unicode Obfuscation
 Silverlight XAP, APPX and APK Package Character Set
Support  Automatic Obfuscation of
 XAML Parsing for Silverlight Applications Satellite Assemblies
 Assembly Merging  Public Symbol Obfuscation
 Assembly Embedding  Revisited Control Flow
 Embedded Resources Encryption Obfuscation
 MSIL Encryption  Improved Overload Renaming
 Anti-Reflection Protection  Extended XML Rules Files
 XAML and BAML Obfuscation  SNK and PFX File Support
 Dynamic Proxy Calls to External and Internal  Extended Command Line Help
Methods  More than 50 Command Line
 Code Instrumentation Options
 Enhanced Control Flow Obfuscation  Custom Plugins
 Enhanced String Encryption  Debugging Protection

The Free Babel Obfuscator Version 2.0.0.1

 Support NET Framework 1.1, 2.0, 3.5


 Obfuscate Namespace, Type (also generic types), Method, Events, Properties and Fields
 Unicode Normalization
 Support Generic Types and Virtual Function Obfuscation
 Basic Control Flow Obfuscation
 Basic String Encryption (XOR algorithm only)
 Dead Code Removal (methods only)
 Selective Obfuscation with XML Rule Files
 Declarative Obfuscation using Custom Attributes
 MSBuild Integration
 SNK Strong Name Signature
29

Overview

The following sections will guide you through the software setup and basic understanding of command-line
usage. The section Processing Phases will be a review of the obfuscation process performed by Babel. If you
want to start using Babel right away, you can begin by reading from the Rules File section, just to get a basic
understanding of how to configure the obfuscation process. Babel comes with extended command-line help
syntax so that you can access the detailed help of each command line option by typing babel –help (option
name). The code transformations performed by Babel are grouped into phases. This manual will show you in
detail what each phase does and how it can be configured using XML rules files. Following are the Visual
Studio Integration and MSBuild Task sections. Those sections explain how to use Babel within Visual Studio
and how to integrate the Babel Obfuscator into automated build processes. In the Advanced Topics section
you will find some useful tips on improving your obfuscation and getting the most out of Babel. I have also
included a quick reference explaining the warning messages that Babel can output (Appendix A).

If you have any comments or suggestions about the software, the website, or this help guide, please contact
our support at support@babelfor.net
30

Using Babel Obfuscator


This section will describe how to setup Babel Obfuscator and the basic usage of the user interface. The Babel
Obfuscator User Interface allows the user to obfuscate an application in few steps making easy to generate
obfuscation project files that are compatible with MSBuild. Then you will find a detailed description of the
command line interface and the XML Rules Files that are available to configure the obfuscation process.
31

Setup Babel on Windows

Babel Setup is available for 32-bit and 64-bit Windows platform as an MSI installer package. The deployment
package is named babel_x86_9.3.3.0.msi for 32 bit and babel_x64_9.3.3.0.msi for 64-bit operating systems.
They both provide the same compiled executable targeting all platforms. The only difference is in the location
of the installed files.

The 32-bit setup will install the Babel folder under the Program Files folder, whereas the 64-bit version will
install the Babel folder under the Program Files 64 folder. If you run the setup package suited for 32-bit
version on 64-bit operating systems, the Babel folder will be copied under the Program Files (x86) directory.

! NOTE
If you have a previously installed version of Babel Obfuscator, uninstall it from Control Panel before
installing the new version.

To install Babel, launch the Setup MSI installer. This package will guide you through the install process. On
Vista and Windows 7 operating systems you should confirm the Allow button in the User Access Control
dialog during installation.

Once installed, if you want to launch Babel from the DOS command shell, add the babel.exe executable file
path to the environment user variable PATH. Open

• Start > Control Panel > System > Advanced system settings > Environment Variables.

In the User variables list box double click the PATH variable. Or if that does not exist, press the New button
and edit in the New User Variable Dialog the following fields:

Variable name: PATH


Variable value: C:\Program Files\Babel

Variable value field should point to the installation path.


Now you are ready to open a command shell and start babel.exe.
32

Setup Babel for Mono on MAC OSX

Babel Obfuscator is available to run on Max OS X. To install Babel Obfuscator under Mac OS X please
extract the babel_mac_9.3.3.0.zip package in /Applications/Babel folder and copy in the same folder your
license file babel.licenses.

Then install Babel.Build.dll into the mono GAC with the following command:

sudo gacutil –i /Applications/Babel/Babel.Build.dll

To access babel.exe, you can add /Applications/Babel to the $PATH variable by exporting it to your
.bash_profile file.

export PATH=$PATH:/Applications/Babel

Create a bash script under /Applications/Babel named babel containing the following lines:

#!/bin/bash
mono /Applications/Babel/babel.exe "$@"

Save the babel script and enter:

chmod +x babel

Now if you open a Terminal windows you can start babel typing:

babel myassembly.dll
33

Setup Babel dotnet CLI Tools on Linux and MAC OSX

Babel Obfuscator and Licensing tools are available to install as NuGet packages for all Company license
subscribers. Starting from dotnet 3.0 you can install Babel Obfuscator and Licensing as dotnet CLI global tool
on MAC and Linux OS by running dotnet tool install at command line.

Configure NuGet
Babel Obfuscator and Licensing tools for dotnet are available from the Babel.Obfuscator.Tool.X.Y.Z,nuget and
Babel.Licensing.Tool.X.Y.Z.nuget packages respectively. Where X.Y.Z refers to the package version.
To install the packages, you should put both packages inside your private NuGet repository.

If you have not configured a private NuGet repository, you can create a NuGet repository on your local
machine by editing the NuGet.Config file.

Create the NuGet folder under your local user folder:

mkdir ~/NuGet

Then open the NuGet.Config file located at:

MAC OSX ~/.nuget/NuGet/NuGet.Config

Linux Ubuntu ~/.nuget/NuGet/NuGet.Config

And add a new package source named Babel pointing to the ~/NuGet local folder you just created:

MAC OSX <add key="Babel" value="/Users/username/NuGet" />

Linux Ubuntu <add key="Babel" value="/home/username/NuGet" />

Where username is the local user folder, for example:

<?xml version="1.0" encoding="utf-8"?>


<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json"
protocolVersion="3" />
<add key="Babel" value="/home/babel/NuGet" />
</packageSources>
</configuration>

Now copy the Babel.Obfuscator.Tool.X.Y.Z,nuget and Babel.Licensing.Tool.X.Y.Z.nuget packages files into


the ~/NuGet folder you created before.

Install the Tools


Once the Babel tool packages are in your local NuGet repository, you can install the tools using dotnet install
tool at command line.

Install Babel Obfuscator CLI tool:

dotnet tool install Babel.Obfuscator.Tool -g

Install Babel Licensing CLI tool:

dotnet tool install Babel.Licensing.Tool -g


34

To check the tools are installed enter:

dotnet tool list -g

Package Id Version Commands


------------------------------------------------
babel.licensing.tool 9.3.2 lic
babel.obfuscator.tool 9.3.2 babel

You can invoke babel and lic tools from command line.

Setup the License File


Before using the Babel CLI tools, you need to install the Babel license file.
Note that the license file should be the one you received with the tools. If you are not sure about the license
file, please check out the Troubleshooting License File Issues paragraph.

To install the license file, copy the file babel.licenses to a local folder on your machine. This can be for
example ~/Babel. To get Babel tools to find the license file, please define the environment variable
BABEL_LICENSE_PATH pointing to full license file path:

export BABEL_LICENSE_PATH=~/Babel/babel.licenses

If you want to setup the license file environment variable for the current user, export the environment variable
in your bash profile file:

MAC OSX ~/.bash_profile

Linux Ubuntu ~/.bashrc

Add to your bash profile file the following line:

export BABEL_LICENSE_PATH=~/Babel/babel.licenses

To activate the changes, enter at command line:

MAC OSX source ~/.bash_profile

Linux Ubuntu source ~/.bashrc

You can test your license file is installed properly by entering at command line:

babel --license
35

Babel Obfuscator User Interface

To start Babel Obfuscator user interface, browse:

 Start > All Programs > Babel > Babel

The user interface will be started with the Input navigation link selected.

1) Main Toolbar
2) Available functional groups

Obfuscation A selection of functionalities related to obfuscation


Licensing Functionalities dedicated to licensing (Company license)
Data Licensing database (Company license)
Tools General tools

3) List of functionalities related to the chosen group


4) View of the selected function

For more information about Licensing and Data features please refer to the Babel Licensing user’s guide.
36

Creating a New Solution File

 In the Input Grid select the File column in the first available row and click the browse button.
 Browse for a Primary Source Assembly: a .NET Framework EXE or DLL file or a XAP/APPX Package.
 Save your project by selecting from the main menu: File > Save As and save the solution file with
.babel extension.

The Babel solution file is an MSBuild XML file that groups a set of Babel obfuscation projects. Each project
holds the Babel MSBuild task configuration to obfuscate an assembly inside the solution. This allows the user
to launch the obfuscation from the command line using the MSBuild tool.

You can add more assemblies to your solution by repeating the above steps 1 and 2.

You can also drag & drop one or more Primary Source Assemblies from Windows Explorer directly into the
Input Grid.

Each Primary Source Assembly added, will be shown in a separate row of the Input Grid. By clicking on the
expand button near the input File column, the additional file grids will be shown. There are five tabs: Inputs,
Rules, Maps, Plugins and Search Directories.
37

The Input section is where you can choose the assemblies you want to merge or embed into the primary
assembly. The Rules section is where you can add your XML rules files that Babel will process when
obfuscating the related primary assembly. The Maps section is where to add XML input mapping files
generated during the obfuscation of the primary assembly references (see Cross Assembly Obfuscation). The
Plugins section is where to add external babel Plugins used to obfuscate the primary assembly (see Plugins).
The Search Directories section allow you to specify additional directories where babel can search for
referenced assemblies.

You can always use drag & drop from Windows Explorer to add your files to each of the available sections.

! NOTE
In case you have many primary assemblies in your input grid and you want to add an XML rule file to more
than one primary assembly, just expand one of the primary assembly row where you want to add the XML
rule file, select the Rules tab, then select in the Input grid all the other primary assembly rows where you want
the XML rules to be applied. From the expanded Rules tab press the browse button and choose the XML rule
file. The file will be added to all the selected primary assemblies. The same applies for the Inputs and Maps
grids.

Use the bottom grid navigator bar to remove the selected Primary Source Assembly or other files from the
detail’s panels.

The input assembly grid allows you to change the order in which the assemblies are obfuscated by simply
drag & drop each primary source assembly into the desired row. The primary source assemblies are
processed starting from the first row.
38

Changing Obfuscation Settings


Once you have set up all your inputs assemblies, you can proceed to the Settings link to configure the
obfuscation options:

• Click the Settings link on the Group Navigation Panel to change to the obfuscation settings.
• In the program toolbar ensure that the name of the primary assembly you want to change obfuscation
settings is selected.

You can press the Propagate changes button


on the toolbar next to the Primary Assembly
drop down. When the Propagate changes
button is pressed, all the changes made to the
selected Primary Source will propagate to all
the Primary sources loaded in the Input Grid.

On the left panel drag the Obfuscation Level slider up to increase the obfuscation amount that will be
performed. You can fine tune settings by changing the options available on each section.

Code Generation Options


You can select the Optimization link on the Navigation panel to setup code generation and optimization
options.

• Select Remove Dead Code if you want to remove all the code that is not reachable from any entry
point in the obfuscated target. Additional entry points can be specified by using regular expressions to
describe the method signature where Babel should start the search.
• You can optimize further, by sealing classes or removing System.Enum types and constant fields
whenever it is possible. Babel can also remove all the custom attributes that are specified in the grid
Attributes.
39

Setting the Output and Building the Project


The Output link in the Navigation panel lets you to set up the output file or folder and some additional
configuration like the strong name signature.

If you want to configure an output folder for all the obfuscated assemblies that are loaded into your
obfuscation project, you can activate the Propagate changes button in the toolbar and then choose from the
drop-down button the Output Folder option. Then browse for the output folder where you want to save all the
obfuscated assemblies. You can check that the output folder is set for all the primary sources by changing to
another primary source from the drop down in the toolbar.

On the application toolbar click the Start button to start the obfuscation.
40

1) Primary Source Assembly obfuscation progress


2) Overall Obfuscation progress

The Console navigation link will let you examine the Babel Obfuscator output while the obfuscation is running.
You can select the Primary Source from the drop-down toolbar to see the relative obfuscation output.
41

Examine the Obfuscated Assemblies


To browse for the Obfuscation output folder, click the up-arrow button located next to the Output File /
Output Folder text box. Then you can drag the output assembly into .NET Reflector to examine the
obfuscated code or simply run the application.
42

Deobfuscating Stack Trace


When an obfuscated assembly crashes, it is difficult to get useful information from the exception stack trace
because most of the time it contains the obfuscated methods names. Babel can make obfuscated stack trace
readable using the XML mapping files produced during the obfuscation process. To de-obfuscate the stack
trace you can select the Stack Decoder link available in the Tools navigation group.

• Select Tools in the navigation group then click the Stack Decoder link.
• In the XML Map File grid browse for one or more XML map files that were generated during the
obfuscation of your application.
• Paste the obfuscated stack trace into the Obfuscated Stack Trace text box.
• Click the Deobfuscate Stack Trace button

The translated stack trace will be shown in the Deobfuscated Stack Trace text box.

Deobfuscated Stack Trace and Overloaded Renaming

When overloaded renaming is enabled Babel renames all the methods of a given type with the same name as
long as this is permitted by CLR rules. This makes more difficult to reconstruct the correct stack trace from the
obfuscated one because each obfuscated name might have more than one match:
43

Acme.ViewModel.ViewModel.MainViewModel.LoadData()
=> Acme.ViewModel.ViewModel.MainViewModel.CloseWindow()
=> Acme.ViewModel.ViewModel.MainViewModel.CleanUp()
Acme.ViewModel.ViewModel.MainViewModel.get_Message()

In this case Babel will show in every line of the obfuscated stack trace, all the possible methods matched to
the main guess.
44

Command Line Tool


Babel Obfuscator is available as a command line tool babel.exe.
To start babel.exe from the command line, locate in the Start Menu the Babel Command Prompt:

 Start > All Programs > Babel > Babel Command Prompt

You can launch babel.exe using the following syntax:

babel.exe <primary assembly source> [<other assemblies>...] [options]

The <primary assembly source> is the target assembly or an assembly package (whether an APPX or XAP
package) that we want to obfuscate. This parameter is mandatory.

!
! NOTE
In the Babel command line syntax, every mandatory parameter is surrounded by angle brackets <…>,
whereas every optional parameter is surrounded by square brackets […].

The [<other assemblies>…] is an optional list of assemblies that will be merged with the primary assembly.
The [options] are a list of command line switches that control the behavior of Babel. There are many options
and they are grouped into several sections:

Babel has numerous command line options, but there are two distinct kinds of options: short options and long
options. Short options are a single hyphen followed by a single letter ex:

-t -p -f

Long options consist of two hyphens followed by several letters ex:

--types –properties --fields

Every option has a long format and sometimes an alias as well. But only certain options have an additional
short format (these are typically options that are frequently used).

To maintain clarity, we usually use the long form in the examples, but when describing options (if there's a
short form) we'll provide the long form to improve clarity and the short form to make it easier to remember.
You should use whichever one you're more comfortable with.

An option may have an alias. Aliases provide shortcuts for long options.
For example, the --keyfile option has the following aliases:

--key-file
--kf

Note that if the option consists of several words, a dash can be used to separate each word. The help
command can display all the aliases available for a given option.

When Babel parses long option names, it uses auto abbreviation to resolve the option. So --statistics can be
shortened to --stat.
45

Some options can be negated. These options are like switches that can be turned on or off according the no
or no- option prefix. For example, the --types enables type name obfuscation whereas --notypes,
--no-types or -not will disable it.

Miscellaneous

This section contains all general options that are used to configure the console output and other aspects of
the obfuscation process.

--help [option] (?)


Typing Help without any parameters shows the main help menu with all the options available and a short
description. When [option] name is specified, Babel will show extended help with the detailed command
description.

C:\> babel --help stringencryption


stringencryption (nostringencryption, no-stringencryption)
usage: --[no]stringencryption [name]
Enable ([no]disable) string encryption (default: enabled)

When enabled, all the user strings into the target assembly will be encrypted.
The optional parameter name sets the encryption type.

The short form for this option is invoked by the character “?”.

--[no]logo (enabled)
This option shows the Babel copyright message. If the optional prefix [no] is specified, the copyright message
will not be shown.

--license [path]
Displays available license information. If a valid license is not found, an error message will be displayed.
The optional parameter [path] can be used to set the license file path or search directory. If not specified, the
license file will be loaded from the folder where babel.exe has been started.

--verbose <n> (v)


Sets the console output verbosity level when <n> is 0 or higher. If 0 is specified, no messages are displayed
during obfuscation; only warning messages and the Babel logo are displayed.

--noconfig (@) (disabled)


Do not load default configuration command line values. When specified, all the default values stored in
babel.exe.config file are ignored.

Examples:

babel myapp.exe --noconfig --agent -tpm

babel myapp.exe @ --agent -tpm

Will obfuscate myapp.exe types, properties and methods with the agent analysis enabled.
46

--nowarn <warn list>


Suppress the notification of one or more warning messages. The <warn list> parameter represents a list of
warning ID separated by a comma character. Babel will silently ignore warning numbers passed to the nowarn
option. All available warning IDs are listed in Appendix A.

--[no]warnaserror [warn list]


Specifies a list of warnings that should be treat as errors halting the obfuscation process. The [warn list] is an
optional comma-delimited list of the warning ID to which the warnaserror option applies. All available warning
IDs are listed in Appendix A.

--[no]statistics (enabled)
When enabled, outputs phase processing statistics just before exiting the program.

--[no]agent (a) (enabled)


This option enables or disables Agent Phase. When enabled, the Agent performs static code analysis to find
symbols that should not be obfuscated.

--[no]satellite [assembly]
Treat [assembly] file as a satellite assembly of the target assembly. Babel will add to the list of satellite
assemblies automatically discovered all the assemblies specified with this switch at the command line.

--addsearch <path>
Adds the specified directory <path>, to the list of folders where Babel searches for referenced assemblies.
The parameter <path> can be a wildcard expression to match a set of directories.

The following special characters can be used to make a wildcard expression:

* matches any number of any characters including none


? matches any single character
** matches any directory recursively
[a-z] matches one character from the range given in the bracket
[!ab] matches any characters that is not in the given bracket

The following special strings can be combined into the path expression for the currently searched assembly:

:assemblyname:
:assemblyversion:
:assemblypublickeytoken:

This option can be entered multiple times.

Examples:

--addsearch .\**\lib
--addsearch .\:assemblyname:\**\netcoreapp2.0

--take <regex>
Process the XAP package assembly names that match a given regular expression. If not specified, Babel will
obfuscate all assemblies that are deployed by the XAP package. These assemblies are found under the
Deployment.Parts element in the AppManifest.xaml file:
47

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="OrbSl3"
EntryPointType="OrbSl3.App" RuntimeVersion="3.0.40624.0">
<Deployment.Parts>
<AssemblyPart x:Name="Silverlight3App" Source="Silverlight3App.dll" />
</Deployment.Parts>
</Deployment>

This option may be specified multiple times.

Examples:

babel package.xap --take ".*gui\.dll" --take ".*engine\.dll"

Will obfuscate all the DLLs file names that ends with “gui” or “engine” words. The match is done using case
insensitive search.

--skip <regex>
Do not process the XAP package assembly names that match a given regular expression.
If not specified, Babel will obfuscate all assemblies that are deployed by the XAP package. These assemblies
are found under the Deployment.Parts element in the AppManifest.xaml (see also --take command).

--compress <n> (6)


Set XAP package compression level (default: 6).
XAP compression level must be between 0 and 9. If 0 is specified, the XAP package will not be compressed
at all. A value of 1 maximizes speed while 9 maximize compression. The default value is 6. High compression
level may reduce XAP package size, increasing the computational time required during decompression.

--quickrule <rule>
Enter a quick rule definition. A quick rule can be used instead of an XML rule when the user wants to
configure the obfuscation process without having to make an XML rule file.

Quick rule syntax:

feature[=exclude];[regex];[access];[target]

Where:

 feature is the name of the feature the rule wants to target


 [=exclude] has to be specified whether we want to disable the feature (On or Off are also accepted
values)
 [regex] is an optional regular expression used to filter all symbols processed. By default, the
obfuscator will take all symbols.
 [access] set the visibility of the symbols that should be processed and can be one of the following
values: Public, Protected, Internal, Private, All (default All)
 [target]specifies the symbol kind. Admitted values are: Classes, Delegates, Structures, Interfaces,
Enums, Events, Methods, Properties, Fields, StaticFields, Resource, All (default All)

The quickrule switch can be entered multiple times. Quick rules will be processed in the order they are
encountered on the command line and before the processing of any XML rule.

Examples:

1. Rename all public symbols


48

babel myapp.exe –quickrule renaming;.*;Public

2. Disables string encryption into MyNamespace namespace

babel myapp.exe –quickrule "string encryption=exclude;MyNamespace.*;All;Methods"

3. Encrypt all methods defined into Licensing class:

babel myapp.exe –quickrule "msil encryption=on;MyApp.Licensing.*"

--[no]removekey
Removes the strong name signature from the target assembly.

--dbghelpdlldir <path>
Set the directory to dbghelp.dll.

--trace <regex>
Enable obfuscation tracing for symbols whose signature matches the given regular expression.

--randomseed <seed>
Set the seed used to initialize the random number generator.

--use <key=value>
Set usage options as key value pair.
Usage options:

 experimental=[on/off] Whether to enable experimental features (off)


 parallel=[on/off] Whether to perform multithread obfuscation (on)
 loadtomemory=[on/off] Whether to load assemblies to memory (on)
 tagassembly=[on/off] Whether to tag the target assembly with the BabelObfuscator attribute (off)

--detectifobfuscated [action]
Whether to detect if the target assembly is already obfuscated.
This option can work when the target assembly is tagged with BabelObfuscator attribute (see use option).
In case the obfuscated assembly was not tagged, it may not work properly.

Admitted actions are:

 warn output a warning and continue processing the assembly


 skip exit without processing the assembly

Plugins

--plugin <file>
Set Babel plugin file path. This option may be specified multiple times. (see Plugins)
49

--argument <key=value>
Set plugin argument as key value pair. This option may be specified multiple times.

Merge and Embed Assemblies

Assembly merging combines a list of assemblies into the primary assembly. This functionality is similar to that
provided by ILMerge, a tool freely available at Microsoft .NET Framework Developer Center. Babel has its
own merging algorithm that has been proven to be more efficient and less error-prone than the one provided
by ILMerge. Babel merges and obfuscates all the assemblies that are listed after the primary assembly in the
command line.

--[no]internalize (disabled)
If enabled, all the externally visible types in the merge assembly list have their visibility restricted so that only
the target assembly may use them.

--[no]copyattrs [regex] (enabled)


When this option is enabled, all the assembly level attributes of each input assembly are copied into the target
assembly. An optional regular expression can be specified to allow the merging of duplicate attributes that
match the given regular expression.

--embed <assembly>
Babel can embed multiple dependency assemblies into the target assembly. The embedded assemblies are
compressed and encrypted. Embedding can simplify the deployment and reduce the size of the software. It
can be used instead of merge when there is no need to fully obfuscate the dependency assembly.

This option can be specified multiple times.

babel.exe myapp.exe --embed Library1.dll --embed Library2.dll

Renaming

This command line section describes the commands that can be used to configure symbol renaming.

--[no]types (t) (enabled)


If disabled, types are not renamed.

--[no]events (e) (enabled)


If disabled, events are not renamed.

--[no]methods (m) (enabled)


If disabled, methods are not renamed.

--[no]parameters (r) (enabled)


If disabled, parameters are not renamed.
50

--[no]properties (p) (enabled)


If disabled, properties are not renamed.

--[no]fields (f) (enabled)


If disabled, fields are not renamed.

--[no]xaml (x) (disabled)


If enabled, symbols used in XAML and BAML resources are renamed. This option can accept optional key
value pair specified as <key>=<value> that configures the renaming process. The configuration options
accepted are:

 keys = {On/Off} Whether to enable renaming of dictionary keys


 res = {On/Off} Whether to enable renaming of BAML/XAML resources
 strip = {On/Off} Whether to strip line information or white spaces
 manual = {On/Off} Whether to use manual symbol renaming

--[no]virtual (enabled)
If disabled, virtual members such as methods, properties and events, are not renamed.

--[no]overloaded (disabled)
If enabled, Babel uses the same name for two or more methods of the same type during obfuscation.

--[no]flatns (n) (enabled)


If enabled, all the types are moved into the global namespace. This flattens the namespace hierarchy and no
namespace information is embedded into the obfuscated assembly.

--[no]unicode [char set] (enabled)


If enabled, the names are replaced with unreadable Unicode strings. With Unicode normalization disabled all
the obfuscated names are made by strings of lowercase characters taken from the Latin alphabet. Optionally
the user can specify the character set used to generate obfuscated names (see Unicode Character Set).

--namelength <n> (1)


Set the minimum name length of renamed symbols. Optionally key value pairs can be entered to set the
minimum length of types, methods, properties, fields and events separately.

 types=<n>
 methods=<n>
 properties=<n>
 fields=<n>
 events=<n>

Example:

babel.exe myapp.exe --namelength types=12 --namelength methods=3


51

--nameprefix [prefix]
Set the name prefix of renamed symbols. Optionally key value pairs can be entered to set the prefix of types,
methods, properties, fields, events and parameters separately.

 types=prefix
 methods=prefix
 properties=prefix
 fields=prefix
 events=prefix
 parameters=prefix

Example:

babel.exe myapp.exe --nameprefix types=$Name_ --nameprefix methods=M_

The special value $Name is replaced with the original symbol name. The $Name prefix can be used to debug
renaming issues.

--[no]xmldoc [file|regex] (enabled)


Whether to update the target assembly XML documentation by filtering all renamed symbols. Optionally the
XML document file path or a regular expression can be specified.

If the file name or the regular expression match the XML documentation file name of a merged assembly, the
XML documentation of the merged assembly will be merged into the XML documentation of the target
assembly.

Control Flow Obfuscation

The MSIL Control Flow Obfuscation phase is processed when either controlflow or invalidopcodes are present
in the command line. This phase produces a transformation of the method MSIL changing the code execution
path so that results are difficult to understand.

--[no]controlflow (enabled)
If enabled, methods’ control flow is altered. Key-value pair <key>=<value> can optionally be entered to
configure code scrambling. The configuration options accepted are:

Produces verifiable MSIL code

 goto = {On/Off} Whether to insert irrelevant branches


 switch = {On/Off} Whether to enable switch scrambling
 case = {On/Off} Whether to hide case constants
 if = {On/Off} Whether to enable if scrambling
 call = {On/Off} Whether to enable random calls
 value = {On/Off} Whether to use value encryption
 token = {On/Off} Whether to enable emission of method tokens

Produces not verifiable MSIL code

 underflow={On/Off} Whether to generate stack underflow


52

--iliterations <n>
Set the number of iterations used in the control flow obfuscation algorithm. Setting the number of iterations to
0 will disable control flow obfuscation. Increase the value <n> to increase the number of branch instructions
inserted into each method.

--[no]invalidopcodes [mode] (disabled)


Use this option to emit invalid MSIL op-codes at the beginning of every method. This will stop reflection tools
like .NET Reflector to display IL method disassembly. Warning: This will make your assembly not verifiable.
Normally, code that is not verifiable cannot run on x64 Operating Systems. This option should be switched off
if the obfuscated assembly targets x64 platforms.

The optional parameter [mode] enables different IL emission configuration. Accepted values are:

 enhanced: Insert additional invalid op-codes.


This mode is not compatible with .NET Framework 1.x.

Encryption and Protection

MSIL encryption option enables the encryption of the method IL code. By default this option by itself does
nothing if the encrypted methods are not explicitly assigned to be encrypted by means of rules or with suitable
custom attributes. This explicit method designation is required because the resulting encrypted method call is
much slower than the original one and the user should be aware of all the methods that will be encrypted in
the target assembly.

--[no]msilencryption [regex] (disabled)


If enabled, MSIL Encryption Phase is performed and all the methods that were designated for encryption will
be processed. The methods that will be encrypted are those matching the optional regular expression or rules
defined into XML files. This option can be specified multiple times.

--[no]stringencryption [name] (enabled)


This option, when enabled, tells Babel to encrypt all the user strings into the target assembly. If the optional
parameter name is provided, the encryption will be performed according the algorithm specified.

The known algorithm names are:

 hash – compressed hash table:


The strings are arranged into an hash table data that is compressed and encrypted. This
algorithm ensures also tamper protection.
 xor – inline XOR encoded strings

The default algorithm is hash when a valid license is present, otherwise is the xor algorithm.

--[no]valueencryption [key=value] (disabled)


This option enables the encryption of inline constant values and arrays. Key-value pair <key>=<value> can
optionally be entered to enable or disable the encryption of some defined types.

The configuration options accepted are:

 int32 ={On/Off} Whether to encrypt Int32 values


 int64 = {On/Off} Whether to encrypt Int64 values
 single = {On/Off} Whether to encrypt Single values
53

 double = {On/Off} Whether to encrypt Double values


 array ={On/Off} Whether to encrypt Arrays

--[no]ildasm (enabled)
When enabled, Babel applies the System.Runtime.CompilerServices.SuppressIldasmAttribute attribute to the
assembly to prevent the Microsoft MSIL Disassembler: ILDASM (Ildasm.exe) from disassembling the
obfuscated target.

--[no]reflection (enabled)
Enables or disables emission of invalid metadata to stop reflection based tools.

--[no]resourceencryption (disabled)
Enables or disables resource encryption. When enabled, all the embedded resources are compressed and
encrypted.

--[no]proxy [type][;regex] (disabled)


Enables or disables the generation of proxy calls to external/internal methods. The optional parameter [type]
can have one of the following values:

 external – hide calls to external assembly methods


 internal – hide calls to internally defined assembly methods
 all – hide both internal and external method calls

Optionally the user can enter a regular expression, after the character “;”, to match the method signature
where Babel should make a proxy:

babel.exe myapp.exe --proxy external --proxy ;System.Array::.* --proxy ;::GetEnumerator

Babel will generate a proxy for all external methods of the System.Array type and all the GetEnumerator calls.

--[no]tamperingdetection (disabled)
Whether to enable tampering detection.

--[no]antidebugging (disabled)
Whether to enable anti debugging protection.
54

Code Generation

With code instrumentation babel, can hook all the methods of the obfuscated target and intercept all methods
entry and exit point or catch any exception occurred.

--addreference <assembly>
Add existing assembly file to the list of references. This option can be specified multiple times

--[no]instrument [regex] (disabled)


When this option is enabled, all methods declared into the target and merged assemblies are instrumented.
An optional regular expression can be specified to target the fully qualified members that should be
instrumented.

Fully qualified members have the following syntax:


[NamespaceName].[TypeName]::[MethodName]

Example:

babel.exe myapp.exe –-instrument mynamespace\.mytype::.*

This option can be entered multiple times.

--[no]emptymethods (enabled)
Enables or disables the instrumentation of empty methods.

--[no]deadcode [regex] (disabled)


Enable or disables the Dead Code Removal phase. When enabled, removes all methods, properties and
events that are unused. An optional entry point can be specified through [regex] to define where to start the
search.

--[no]seal (disabled)
When enabled seal all non-public classes that are not used as base class in an inheritance hierarchy.

--[no]cleanattrs <regex> (disabled)


Enable or disables (no) the removal of unwanted attributes. The <regex> parameter is a regular expression
that match the unwanted attribute type full name. This option can be specified multiple times.

--[no]enumremoval (disabled)
Enable or disables the removal System.Enum types whenever possible. The System.Enum fields are replaced
with their constant values.

--[no]constremoval (disabled)
Enable or disables the removal of constant fields whenever possible. The fields are replaced with their
constant values.
55

--[no]disgregateremoval (disabled)
Enable or disables the removal of property and event metadata information whenever possible.

--[no]inlineexpansion (disabled)
Code inline expansion will allow to substitute a call to method with the body of the method inline.

--moduleinitializer [method]
Add module initializer code. Optionally a static method signature with no parameters can be specified which
will be called after the module loads.

--[no]debug [source] (disabled)


When enabled, Babel will emit the debugging information and generates a PDB debug symbol file in the same
directory of the obfuscated target. Use the --pdb command line switch to change the debug symbol file name
and path. A debug symbol store can optionally be specified.

Examples:

--debug srv*c:\Symbols*http://msdl.microsoft.com/download/symbols
56

Output Files

This section provides Babel the option to set output filenames.

--output <file>
Set the output file path for the obfuscated target. If this option is not provided, the obfuscated target will be
saved into the BabelOut subdirectory of the original assembly folder.

--pdb <file>
Set the output PDB debug symbol file name and path. This option can be used to change the default debug
file symbol name when the --debug option is enabled.

--pdbpwd <password>
Set debug information file password. The password will be used to encrypt the source code file names stored
into PDB.

--logfile <file>
Send the Babel output messages to a log file.

--mapout [file]
Set the output file name for the XML obfuscation map. If the optional parameter [file] is not provided, Babel will
name the XML map file as the original assembly name, adding the extension “.map.xml”.

--makeproject [file]
Build an MSBuild project file from the entered command line. If the optional parameter [file] is not provided,
Babel will save the project file into the BabelOut subdirectory.

Input Files

The Input Files section contains options that are used to pass additional inputs to Babel.

--keyfile <file>
Set the strong name file used to re-sign the obfuscated assembly and localized resource DLLs.

The supported file formats are: Strong Name Key (.snk) and Personal Information Exchange (.pfx).
When a .pfx file is used, Babel will ask the user to enter the password during obfuscation in case it was not
specified in the command line option (--keypwd <password>).

--keyname <container>
Use this option to re-sign the application if the key pair is stored in a key container. The mandatory
<container> parameter represents the key container name used to re-sign the obfuscated assembly and
localized resources DLLs.
57

--keypwd <password>
Specifies the password requested by a Personal Information Exchange (.pfx) file to re-sign the obfuscated
assembly. When the password is not specified from the command line, Babel will require the user to enter the
proper password during the obfuscation process.

--keystore <file>
Set the android keystore location. This option can be set to resign the obfuscated APK package.

babel.exe --keystore debug.keystore --keypass android --storepass android


--keyalias androiddebgkey

--keypass <password>
Set the android keystore password.

--keyalias <alias>
Specifies the android keystore alias.

--storepass <password>
Set the android store password.

--rules <file>
Set the input XML rule files used by Babel to configure the obfuscation process. This option can be specified
multiple times. The rules files will be processed according to the order in which they are entered the command
line.

babel.exe myapp.exe --rules ruleset1.xml --rules ruleset2.xml

--mapin <file>
Set the input XML obfuscation map file that will be used to obfuscate the names of referenced symbols. This
option can be specified multiple times.

--project <file>
Start the obfuscation using the project file specified.

--stacktrace <file>
Deobfuscate stack trace file. This option requires to pass a text <file> containing the obfuscated stack trace
and a set of XML mapping files to deobfuscate the stack trace content.

babel.exe --stacktrace obfuscatedstacktrace.txt --mapin myapp.map.xml


--mapin mylib.map.xml
58

Configuration File

Each option that can be passed to the command line has a default value that is stored in the babel.exe.config
application configuration file. When the user does not explicitly specify an option at the command line, Babel
will use the default value for that option. Default values are loaded from the babel.exe.config file. The
application configuration file is a standard .NET XML configuration file. It contains elements which are
name/value pairs for configuration information.

It is possible to change the babel.exe default values from Babel Obfuscator user interface by opening the
Options dialog and choosing the Settings node:

The following table shows all available configuration properties:

Name Default Type


Value
AssemblySearchDirectories empty System.Collection.Specialized.StringCollection
AutomaticClassSealing True System.Boolean
BabelProjectAddNewLineOnAttributes False System.Boolean
CleanupUnwantedAttributes True System.Boolean
ConsoleForeColorDebug DarkGray System.ConsoleColor
ConsoleForeColorError Red System.ConsoleColor
ConsoleForeColorInfo White System.ConsoleColor
ConsoleForeColorWarning Yellow System.ConsoleColor
ConsoleHighlight True System.Boolean
ConstFieldsRemoval False System.Boolean
ControlFlowAddBranches True System.Boolean
ControlFlowAddMethodToken False System.Boolean
ControlFlowAddSwitchStatement False System.Boolean
59

Name Default Type


Value
ControlFlowChangeIfStatement False System.Boolean
ControlFlowComplexifyDecryptStringCalls False System.Boolean
ControlFlowEncryptSwitchValue False System.Boolean
ControlFlowHideCaseConstants False System.Boolean
ControlFlowIterationCount 3 System.Int32
ControlFlowObfuscation True System.Boolean
ControlFlowRandomCall False System.Boolean
ControlFlowStackUnderflow False System.Boolean
CopyAttributes True System.Boolean
DeadCodeElimination False System.Boolean
DeadCodeRemovalWhipeoutObjectVirtuals False System.Boolean
DisableWarnings empty System.Collection.Specialized.StringCollection
DisgregateRemoval False System.Boolean
DynamicProxy none System.String
DynamicProxyCallFilters empty System.Collection.Specialized.StringCollection
EmitInvalidOpcodes False System.Boolean
EmitInvalidOpcodesMode empty System.String
EnumTypeRemoval False System.Boolean
ExperimentalFeature True System.Bolean
FlattenNamespaces True System.Boolean
GenerateDebug False System.Boolean
Instrument False System.Boolean
InstrumentEmptyMethods True System.Boolean
Internalize False System.Boolean
MakeAppxExeOptions System.String
MakeAppxExePath System.String
MapFileNameEncoding Base64 System.String (Base64/None)
MinimumEventNameLength 0 System.Int32
MinimumFieldNameLength 0 System.Int32
MinimumMethodNameLength 0 System.Int32
MinimumNameLength 0 System.Int32
MinimumPropertyNameLength 0 System.Int32
MinimumTypeNameLength 0 System.Int32
MsilEncryption False System.Boolean
ObfuscateEvents True System.Boolean
ObfuscateFields True System.Boolean
ObfuscateMethods True System.Boolean
ObfuscateProperties True System.Boolean
ObfuscateTypes True System.Boolean
ObfuscateVirtualFunctions True System.Boolean
ObfuscateXaml False System.Boolean
ObfuscationAgent True System.Boolean
OverloadedRenaming True System.Boolean
ParallelExecution True System.Boolean
ProcessReferencedSymbolNames True System.Boolean
ResourceEncryption False System.Boolean
ResourceNameSearchFilters System.Collection.Specialized.StringCollection
SearchSatelliteAssemblies True System.Boolean
ShowLogo True System.Boolean
ShowStatistics True System.Boolean
StringEncryption True System.Boolean
StringEncryptionAlgorithm empty System.String
SuppressIldasm True System.Boolean
SuppressReflection False System.Boolean
TimestampEnabled False System.Boolean
TimestampFormat System.String
UnicodeNormalization True System.Boolean
UnwantedAttributes <list> System.Collection.Specialized.StringCollection
60

Name Default Type


Value
ValueEncryption False System.Boolean
ValueEncryptionInt32 True System.Boolean
ValueEncryptionInt64 True System.Boolean
ValueEncryptionSingle True System.Boolean
ValueEncryptionDouble True System.Boolean
ValueEncryptionArray True System.Boolean
VerboseLevel 1 System.Int32
WarningsAsError empty System.Collection.Specialized.StringCollection
XamlManualRenamePublic False System.Boolean
XamlObfuscateResourceKeys True System.Boolean
XamlStripLineInfo True System.Boolean
XapCompressionLevel 6 System.Int32
XapSkipList <list> System.Collection.Specialized.StringCollection

The default value for DisableWarnings, WarningsAsError and XapSkipList are empty
System.Collection.Specialized.StringCollection. To add elements to these configuration sections you should
add an ArrayOfString element. For instance to add elements to the DisableWarnings collection enter the
following XML in the configuration file:

<setting name="DisableWarnings" serializeAs="Xml">


<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>EM0008</string>
<string>EM0010</string>
</ArrayOfString>
</value>
</setting>

Where EM008 and EM0010 are warning IDs. The complete set of warning IDs is listed in Appendix A.
61

Processing Phases

The transformations that Babel performs during the obfuscation process are grouped into phases. We may
define a phase as a processing unit. Babel has a list of Phases that are processed during obfuscation. This
list is not absolute and may vary according to the options passed to the command line. To configure the
obfuscation process with rules it is necessary to understand how Babel organizes the phased layout. The
phases that Babel arranges in its obfuscation list are outlined below in the order they are processed,
according to the option passed to the command line.

Phase List Command Line Options Description


Merge Input Assemblies Phase List of assemblies to process Process XML rules files and
Merge input assemblies.
Post Reader Phase Analyze the target assembly
Build Call Graph Phase Build the method call graph.
Process Rule Phase --rules Process XML rule files
Agent Phase --agent Performs Agent tasks
Dead Code Removal --deadcode, --cleanattrs Remove unused members
Build Map Phase --mapout Build target map document
Code Instrument --instrument Enable code instrumentation.
Code Optimizations --seal Code optimizations
--enumremoval
--constremoval
--disgregateremoval
Dynamic Proxy Calls --proxy Generate dynamic proxies
Renaming --types, --methods, Rename assembly symbols
--properties, --fields, --events
Tampering Detection --tamperingdetection Add tampering detection code
Encrypt MSIL Phase --msilencryption Encrypt MSIL
Encrypt Values Phase --valueencryption Encrypt values and arrays
Encrypt String Phase --stringencryption Encrypt all strings
Control Flow Obfuscation Phase --controlflow --invalidopcodes Scramble MSIL code
Embed Assemblies Phase --embed Embed assemblies
Encrypt Resources Phase --resourceencryption Encrypt embedded resources
Emit Phase Save and sign the resulting
assembly
Table 1 Obfuscation Phases

Some phases are necessary to the build process (such as Post Reader Phase and Emit Phase) and they will
always be present. Other phases are added only when they are needed, like Merge Input Assemblies and
Process Rules. For instance, the Process Rules phase is added when the user specifies a rule file in the
command line. The following diagram shows the flow of the Babel process. The dashed blocks represent the
optional phases.
62

Merge Input Build Call Obfuscation


Post Reader Process Rules
Assemblies Graph Agent

Dead Code Instrument Dynamic


Build Map Optimizations
Removal Code Proxy Calls

Encrypt Control Flow Tampering Debugging


Renaming
Values Obfuscation Detection Protection

Encrypt Embed Encrypt


Encrypt MSIL Emit
Strings Assemblies Resources

This diagram is not complete; there are phases not listed above that are used by Bebel as services of the
main phases.

Obfuscation Agent

The Obfuscation Agent consists of a list of tasks that Babel performs against the target assembly type model
to determinate which symbols should not be obfuscated. The Agent prevents symbol names from being
obfuscated according the Common Language Runtimes design rules. Babel can run a set of preconfigured
tasks, and they are continuously updated in each new product release. Some of these tasks are simple—like
checking fields of serizializable types. Other tasks are more complex and involve MSIL code static analysis.

The Agent works to prepare a safer obfuscation process and most of the time the final obfuscated assembly
will run perfectly. Because the Agent can only perform static code analysis, it may not discover types that are
controlled during execution. For example: the names of types, stored into strings that are built at runtime are
opaque to the Agent. Using those strings as parameters of reflection methods impose a restriction on
obfuscating the relative type or member name. Changing those type names will likely break the obfuscated
assembly. For this scenario, XML rules files, combined with Agent, are the recommended solution.

Babel’s Agent is enabled by default and should be left enabled whenever possible. There is generally no
reason to disable the Agent entirely. But if you want, you can arrange an XML Rules file to skip a particular
task from being processed. This scenario is useful when an XML rule is overridden by an Agent task outcome.
Agent tasks run after the Rules processing phase, so any custom XML Rule enforced on a member will be
overridden by the Agent task. The only way to disable agent rules is to define an XML Rule to switch off the
Agent task on that particular member.

For instance, suppose that you want to obfuscate a public type named RedBlackTree. So you prepare a rule
to force Babel to rename the type:

<Rule name="RedBlackTree" feature="renaming" exclude="false">


<Target>Classes</Target>
<Pattern isRegEx="true">.*RedBlackTree</Pattern>
<Description>Rename RedBlackTree class.</Description>
</Rule>
63

Then you discover that the type was not renamed because the Agent found that the type is serializable, and
serializable types are not renamed. But suppose you don’t care about serialization and you want that type to
be obfuscated. You can get around this in two different ways. One way is to tell Babel to turn off Agent
analysis with the option --noagent. But this is overkill for our purpose, and the application process might be
broken after the obfuscation because the Agent has not run. The better way, however, is to add a second rule
that forces the Agent to ignore the RedBlackTree type when the serialization task is running.

<Rule name="RedBlackTree agent" feature="agent" exclude="true">


<Pattern isRegEx="true">.*RedBlackTree</Pattern>
<Properties>
<TaskNameList>Serializable types</TaskNameList>
</Properties>
<Description>Ignore Serializable types tasks for RedBlackTree.</Description>
</Rule>

In this rule, we have two elements that are meant to be explained.

 The feature is set to agent to tell the rule processor that we want the rule to be applied to the
agent.
 The TaskNameList that contains a list of commas separated task names. In this case contains
the name of the agent task “Serializable types”. This tells the rule processor that we want to
exclude only the analysis carried on serializable types. If the name list is empty, all the agent
tasks are affected by the rule.

List of available Agent task names:

Task name string Description


Reflected enums Ignore enum types that are consumed by reflection methods
Serializable types Do not rename serializable types
Reflected strings Discover symbol name strings consumed by reflection methods
Reflected types Do not rename types consumed by reflection methods
Type consumed by attributes Do not rename types consumed by attributes
Exposed attributes Ignore symbols that expose specific attributes
XAML analyzer Parse XAML resources to discover types that should not be obfuscated
WinRT types Do not rename WinRT <CLR> types
Dynamic language Do not rename symbols used by dynamic language runtime
Table 2 Agent task names
64

Obfuscation Rules
Babel Obfuscator is configured to perform the obfuscation of an assembly according to several input
parameters that can be specified from the command line or by means of project files. The obfuscation is
performed following a set of pre-defined rules, chosen according the target platform and to avoid some
common issue that could break the resulting assembly. Although the rules defined, in most cases, are enough
to prevent common problems due to obfuscation, sometimes user must define its custom rules to configure
Babel to obtain the desired result or making the obfuscated assembly to work as expected.
Obfuscation rules can be specified with XML files or inside code using Attributes already provided by the .NET
Framework. In the following sections we will describe how to create rules files, the XML elements used to
create a rule and the commonly used .NET Framework attributes related to obfuscation.

Rules Files

Babel rules files are XML files that contain information used to customize the obfuscation process. The rules
file consists of a list of rules defined by the XML element <Rule></Rule>. This list is enclosed by the element
<Rules></Rules> that is also the root document element.

Rules Element
<Rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<Rule name="rule 1" feature="default" exclude="false">
</Rule>
<Rule name="rule 2" feature="control flow" exclude="true">
</Rule>
</Rules>

The Rules element attribute version is used to define the current schema version and must be set to "2.0".

Attribute Value Required Type Description


version 2.0 No System.String Define the current schema version
and must be set to "2.0"
targetAssembly - No System.String Specifies the Assembly name where
the rules will be applied
Table 3 Rules element attributes

Rules are processed in the order they are defined in the XML rules file and for assemblies optionally specified
by the targetAssembly attribute. Whenever the targetAssembly attribute is not specified the rules are applied
to all assemblies. Each rule is checked against all the assembly symbols: types, methods, events, properties
and fields. If a symbol is selected by a rule that targets a feature or a group of features, those features will be
enabled or disabled for that particular symbol based on the value (true or false) assigned to the attribute
exclude. When there are two or more rules targeting the same feature for a given symbol, the last rule
declared wins.

Rule Element
The Rule element is used to configure an obfuscator feature. The obfuscator feature is indicated by the name
assigned to the feature attribute.

<Rule name="my rule" feature="default" exclude="false" applyToMembers="false">


...
</Rule>
65

The Rule element accepts the following attributes:

Attribute Is Mandatory Default Description


name Yes - Friendly rule name
exclude Yes - Whether to exclude all the symbols that match
the rule.
feature No default (renaming) The obfuscator feature name as given in Table
4 Obfuscator feature table
applyToMembers No False Whether to apply the rule to all members of a
symbol that match the rule itself.

The feature attribute defines the obfuscator feature on which the rule acts. The name and exclude attributes
are mandatory. The feature attribute is optional, and if not specified refers to the default feature (renaming).
The obfuscator feature strings are fixed. All the supported feature names are listed in the following table:

Feature Description
all All obfuscator features
default Member names obfuscation
agent Obfuscation agent
control flow Control flow obfuscation
dead code Dead code removal
dynamic proxy Dynamic proxy calls
merge Assembly merge
msil encryption MSIL encryption
msil encryption get stream Declare get source stream method
renaming Member names obfuscation
resource encryption Embedded resources encryption
string encryption String encryption
string encryption encrypt method Defines string encrypt method
string encryption decrypt method Defines string decrypt method
value encryption Inline values and arrays encryption
instrumentation Code instrumentation
instrumentation on entry method Defines code instrumentation on entry method
instrumentation on exit method Defines code instrumentation on exit method
instrumentation on exception Defines code instrumentation on exception method
method
optimizations Metadata optimizations
xaml XAML BAML obfuscation
Table 4 Obfuscator feature table

! NOTE
Babel can process multiple XML Rules files. When more than one Rules file is passed into the command
line, the rules declared in each file can override an enforced rule declared in a previously processed file.
So, the order in which the --rule option is passed to the command line is important.

Any Rule element has other child elements: Access, Target, Pattern, HasAttribute, Properties and Description.
The Pattern element is mandatory, whereas the others are optional.

<Access> - Specifies the symbol visibility for the rule. Possible values are: All or any combination of Public,
Protected, Internal, and Private. If the element is not present the default value All is used.

<Target> - Specifies which kind of symbol should be checked. Admitted values are: All or any combination of
Classes, Delegates, Structures, Interfaces, Enums, Events, Methods, Properties, Fields, StaticFields and
Resources. If the element is not present the default value All is assumed.
66

<Pattern> - Can be any wildcard expression or regular expression. The Boolean attribute isRegEx states
whether the pattern is a regular expression. If a regular expression is used, it’s good practice to enclose the
regular expression definition string in a CDATA section, ex.:

<Pattern isRegEx="true"><![CDATA[^Properties.*]]></Pattern>

The regular expression should match one of the following symbols format:

 Types: Fully qualified type name

Acme.Entities.AcmeEntities

Where Acme.DataMining is the namespace name and AcmeEntities is the type name.

 Methods:

Acme.Entities.AcmeEntities::CreateOrder(DateTime, Int32) : Void

Where CreateOrder(DateTime, Int32) : Void is the method signature.

 Properties:

Acme.Entities.AcmeEntities::Orders : IQueryable<Order>

 Fields:

Acme.Entities.AcmeEntities::_orders : IQueryable<Order>

 Events:

Acme.Entities.AcmeEntities::OrderAdded : EventHandler<EventArgs>

<HasAttribute> - Specifies a list of fully-qualified type attributes. If the target has at least one of these
attributes, the rule matches. This element may have the Boolean attribute onEnclosingType. If set to false, the
attribute is checked on the target symbol itself. If the attribute is true, the attribute is checked on the target
symbol enclosing type instead of the symbol itself.

<HasAttribute onEnclosingType="true">System.SerializableAttribute</HasAttribute>

<HasBase> - Specifies a list of fully qualified type names. If the target has one of these base types, the rule
matches. This element may have the Boolean attribute onEnclosingType. If set to false, the base types are
checked on the target type itself. Otherwise, the base types are checked on the target symbol enclosing type.

<Implements> - Specifies a list of fully qualified interface type names or method signatures. If the target
implements at least one of these interface type or method override, the rule matches. This element may have
the Boolean attribute onEnclosingType. If set to false, the interface types are checked on the target type itself.
Otherwise, the interface types are checked on the target symbol enclosing type.

<Properties> Defines a collection of elements used to customize the feature behavior. Each feature may
support a set of property elements. For instance, the following rule sets two properties of the msil encryption
feature: Cache and MinInstructionCount.

<Rule name="DataWriter" feature="msil encryption" exclude="false">


<Target>Methods</Target>
<Pattern>SQLUtils.DataWriter::*</Pattern>
<Properties>
67

<Cache>true</Cache>
<MinInstructionCount>6</MinInstructionCount>
</Properties>
<Description>Encrypt all methods of the DataWriter class.</Description>
</Rule>
68

Follow the list of property elements supported by each feature:

Feature Element Type Description


agent TaskNameList System.String List of comma separated
agent task names.
merge Internalize System.Boolean If true, all types that match
the rule have their visibility
changed to internal.
CopyAttributes System.String List of comma separated
fully qualified type names
and/or regular expressions.
NoCopyAttributes System.String List of comma separated
fully qualified type names
and/or regular expressions.
renaming Internalize System.Boolean If true, all types that match
the rule have their visibility
changed to internal.
DisableOverloading System.Boolean Whether to disable
overloaded renaming.
DisableUnicode System.Boolean Whether to disable Unicode
names.
RenameParameters System.Boolean Whether to rename method
parameters.
NameLength System.Int32 Set the renamed symbol
name length.
NamePrefix System.String Set renamed symbol name
prefix.
string encryption MinInstructionCount System.Int32 Threshold for method
minimum instruction count.
ManInstructionCount System.Int32 Threshold for method
maximum instruction count.
control flow IlIterations System.Int32 The number of iterations to
use in the control flow
obfuscation algorithm.
EmitIvalidOpcodes System.Boolean If true, invalid op-codes are
inserted into the method
definition.
ChangeIfStatement System.Boolean If true, obfuscate if
statements.
AddSwitchStatement System.Boolean If true, switch statements are
inserted into method
definition.
ScrambleControlFlow System.Boolean Whether to produce
spaghetti code inserting
irrelevant branches.
MaxSwitchTargets System.Int32 Set the maximum number of
switch case targets in the
switch control flow
obfuscation.
HideCaseConstantExpressions System.Boolean If true, hide the calculated
constant values in switch
control flow obfuscation.
AddMethodToken System.Boolean If true, load method token
instructions are inserted
inside the method body.
StackUnderflow System.Boolean Whether to enable stack
underflow instructions
generation
69

UseValueEncryption System.Boolean Whether to encrypt switch


jump table values (available
only when value encryption
is enabled).
RandomCall System.Boolean Whether to generate random
calls jump table (available
only when switch control
flow is enabled).
MinInstructionCount System.Int32 Threshold for method
minimum instruction count.
ManInstructionCount System.Int32 Threshold for method
maximum instruction count.
msil encryption Cache System.Boolean If true, the encrypted method
is cached so that the
compilation process is run
only the first time the method
is used.
MinInstructionCount System.Int32 Threshold for method
minimum instruction count.
ManInstructionCount System.Int32 Threshold for method
maximum instruction count.
Source System.String MSIL-encrypted data source
name
dead code - -
resource encryption - -
optimizations ClassSealing System.Boolean Whether to enable class
sealing optimization
UnwantedAttributes System.Boolean Whether to enable removal
of unwanted attributes
EnumRemoval System.Boolean Whether to enable removal
of System.Enum type
ConstRemoval System.Boolean Whether to enable removal
of constant fields
DisgregateRemoval System.Boolean Whether to enable removal
of properties and event
metadata
Table 5 Feature properties

<Description> - Any useful rule description

The following example shows the content of an XML rule files.

<Rules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<Rule name="Properties types" exclude="true">
<Pattern isRegEx="false">*Properties*</Pattern>
<Description>Do not obfuscate Properties namespace symbols.</Description>
</Rule>
<Rule name="Serializable types" feature="default" exclude="true">
<Target>Fields, StaticFields</Target>
<Pattern><![CDATA[*]]></Pattern>
<HasAttribute onEnclosingType="true">
System.SerializableAttribute
</HasAttribute>
<Description>Do not obfuscate fields of serializable types.</Description>
</Rule>
</Rules>
70

The first rule tells Babel to not obfuscate any symbols inside the Properties namespace or whatever symbol
contains Properties in its fully qualified name. The second rule tells Babel to not obfuscate fields of types that
are declared as serializable. The System.SerializableAttribute attribute presence is checked on the
field enclosing type because the XML attribute onEnclosingType is set to true.
71

Custom Attributes

Babel supports declarative obfuscation using the custom attributes System.Reflection.ObfuscationAttribute


and System.Reflection.ObfuscateAssemblyAttribute provided by the .NET Framework starting from version
2.0. This section explains the usage of custom attributes to customize the obfuscation process.

The ObfuscateAssembly Attribute

The System.Reflection.ObfuscateAssemblyAttribute, is an assembly-level attribute that instructs Babel to use


obfuscation rules reserved to private assemblies.

A private assembly is an assembly that will not be used as a library: no other software components will use
the assembly. Private assemblies are fully obfuscated by Babel that will use obfuscation rules to rename all
public symbols.

The following code example shows how to mark an assembly private:

using System;
using System.Reflection;

[assembly: ObfuscateAssembly(true)]

The Obfuscation Attribute

The System.Reflection.ObfuscationAttribute attribute can be used on assembly members like: types, method,
events, properties and fields to configure the action taken for a specific obfuscation feature.

The attribute has a string Feature property that is used to map a string value to a specific obfuscator feature.
The default value of Feature property is “all”. Babel uses “all” to map the complete set of features and “default”
to map the renaming feature. The complete set of feature names are the same supported by rules files and
are listed in Table 2--Obfuscator feature table.

The ObfuscationAttribute has three other Boolean properties: Exclude, ApplyToMembers and
StripAfterObfuscation. They have their default value set to true.

Exclude: indicates whether the obfuscation feature should be excluded for the associated member.

ApplyToMembers: specifies whether the action taken by the obfuscator for the associated type should be
applied to all its members.

StripAfterObfuscation: specifies whether the attribute should be removed after processing.

The following code example shows how ObfuscationAttribute can be used to target a method for MSIL
encryption:

using System;
using System.Reflection;

[Obfuscation(Feature = "msil encryption", Exclude = false)]


public string RandomString(int length, string characters)
{
StringBuilder sb = new StringBuilder(length);
72

for (int i = 0; i < length; i++)


{
int inx = _rnd.Next(characters.Length);
sb.Append(characters[inx]);
}
return sb.ToString();
}

You can set a list features in the feature string:

[Obfuscation(Feature = "renaming,string encryption", Exclude = true)]

For obfuscation features that have properties, Babel support an extended feature definition where a list of key
value pairs can be specified after the name of the feature:

[Obfuscation(Feature = "msil encryption:Source=opt;Cache=true", Exclude = false)]

This allow to configure code encryption for the member targeting the ObfuscationAttribute and set the code
encryption features properties Source and Cache.
73

Edit Rules

The Babel Obfuscator user interface has a convenient way to edit obfuscation rules.
When an assembly is added to a project, the Obfuscation group allow to Edit Rules for any target assembly
added to the project. The Edit Rules view show inside the Object Browser the selected target assembly.

You can add a rule by selecting any symbol inside the Object Browser. To add a rule, right click the symbol
node and from the popup menu select the menu item Add Rule. A submenu will open where you can choose
the obfuscation feature your rule will target. For instance, if you want to prevent the selected symbol from
being renamed, chose Renaming and then Disable Renaming.
74

The list of created rules for the selected symbol are shown on the top right while the Rule Properties panel
shows the properties for the selected rule. The symbol name will be colored according to the feature has been
chosen for the rule created.
75

Merge and Embed


Babel Obfuscator can merge and embed multiple .NET assemblies into the target assembly. This will simplify
the application deployment and increase the protection. Babel can merge also WPF and Silverlight
assemblies although with some limitation.
In this section, we will see how to merge and embed multiple assemblies with the target assembly and how to
use XML rules to change the default merging behavior.
76

Assembly Merging

To merge multiple assemblies with the target assembly, just enter at the command line the file names of the
assemblies that need to be merged after the name of the target assembly:

babel.exe myapp.exe graphics.dll engine.dll

Where the first assembly in the list: myapp.exe is the target or primary assembly, whereas graphics.dll and
engine.dll are the assemblies that will be merged into the primary assembly.

Babel takes the list of input assemblies after the target assembly and merges them into the target assembly.

babel.exe <primary assembly source> [<other assemblies>...] [options]

There are several options that can be used to configure merging at command line and with MSBuild:

--[no]copyattrs [regex]: When enabled, force Babel to copy all assembly-level attributes into the primary
assembly. Note that any duplicate attribute type having AttributeUsage[AllowMultiple = false] will be
discarded. At the command line it is possible to specify an optional regular expression to match the attribute
full name that should be merged. For example, the following command:

--copyattrs .*InternalVisibleToAttribute

Will configure Babel to merge all InternalVisibleToAttribute attributes found in merged


assemblies. All other attributes will be skipped.
It is possible to specify multiple attributes filters using many copyattrs commands:

--copyattrs .*InternalVisibleToAttribute --copyattrs .*AssemblyMetadataAttribute

If you want to disable the copying of assembly-level attributes, just enter at command
line:

--nocopyattrs

And no assembly-level attribute will be merged into the target assembly.


If you have enabled assembly-level attributes copy at command line or MSBuild, you can use
XML rules to filter the attributes to be copied or excluded.
There are two rule properties in merge feature you can use to filter assembly-level
attributes:

These are CopyAttributes and NoCopyAttributes properties. Each property take a regular
expression that will be used to match the assembly-level attribute full type name.

<Rule name="merge attributes" feature="merge" exclude="false">


<Target>Assembly</Target>
<Pattern>*</Pattern>
<Properties>
<NoCopyAttributes>.*TypeLibVersion</NoCopyAttributes>
</Properties>
</Rule>

The CopyAttributes filter expression is exclusive i.e.: if the filter doesn’t match the fully qualified attribute type
name, the attribute will not be merged. The NoCopyAttributes filter will allow you to select all the attributes that
will not be copied, all the other attributes will be merged into the target assembly.

--[no]internalize: When enabled, modifies the visibility of all the merged assembly types from public to
internal. Because referenced types are always public, lowering their visibility to internal ensures name
mangling, improving the overall obfuscation statistics.
77

This option is disabled by default because changing type visibility will prevent the merged types from being
consumed outside of the primary assembly. You can enable this option if the merged types are intended to be
used only by the primary assembly.

If you have enabled the internalize option at command line or with MSBuild, you can internalize types whose
fully qualified name match a regular expression using XML rules.
For instance, the following rules will merge and internalize all the types defined in Utilities namespace.

<Rule name="Utilities namespace" feature="merge" exclude="false">


<Pattern>Utilities.*</Pattern>
<Properties>
<Internalize>true</Internalize>
</Properties>
<Description>
Merge and internalize all types in Utilities namespace.
</Description>
</Rule>

Babel processes rules in the order in which they are declared in the rules file. Each rule for a given feature
can override the previous defined rule.

You can selectively merge types with XML rules using the merge feature setting the exclude attribute to true:

<Rule name="Utilities namespace" feature="merge" exclude="true">

Although this might break the target assembly because Babel does not perform any integrity check on the
resulting assembly. So if you define a rule to prevent the merge of a type instantiated somewhere in the code,
Babel will fail to process the assembly with an error similar to the following one:

An error occurred during phase 'Merge': Error merging type Acme.ViewModel.MainViewModel

Inner Exception:
Error merging type Acme.ViewModel.MainViewModel

Inner Exception:
Error merging method System.Void Acme.ViewModel.MainViewModel::.ctor()

Inner Exception:
Error processing instruction IL_0030: newobj System.Void
Acme.ViewModel.Internal.ModelFactory::.ctor(Acme.ViewModel.MainViewModel)

Inner Exception:
Cannot resolve type: Acme.ViewModel.Internal.ModelFactory [Acme.ViewModel.dll]

In this case, if you want to reduce the size of the merged assembly, better to use Babel Obfuscator dead code
removal feature.

Merging Silverlight and WPF assemblies

Babel can merge Silverlight and WPF assemblies containing XAML and BAML resource streams. Generally,
WPF and Silverlight applications contain XAML and BAML resources that enclose the identity of the merged
assemblies. Babel can de-serialize the resources, modify the assembly identities, and then re-serialize them.
There is only a limitation in this operation. Babel cannot merge two assemblies that contain the same
resource URI inside the XAML/BAML resource dictionary.

For instance, consider we want to merge two WPF assemblies MyApp.exe and Chart.dll. Both assemblies will
have their WPF resources contained in an embedded resource dictionary named MyApp.g.resources and
Chart.g.resources respectively. Suppose now that the two assemblies define a WPF custom control with its
78

template stored into Themes\generic.xaml file. This file is used as a fallback to define the default style for
most controls. In this scenario Babel will have to merge the BAML stream Themes/generic.baml included in
Chart.g.resources resource dictionary into the MyApp.g.resources resource that already contains a BAML
stream with the same name. This scenario is not handled, and the merge will end with the following warning:

Warning [MG0003]: Resource data 'themes/generic.baml' into Chart.g.resources has already


been added.

The resulting assembly may not work especially when the resources files are different.

Babel can merge also assemblies inside a Silverlight XAP package with the target assembly. When
obfuscating a XAP package, the target assembly is the entry point assembly defined in the AppManifest.xaml
file. The assemblies that will be merged are listed at the command line after the XAP file name:

babel.exe myapp.xap graphics.dll engine.dll

Where myapp.xap is the XAP package containing the target assembly and the two merged libraries:
graphics.dll and engine.dll. Note that in the resulting XAP file the two merged libraries will be removed.

Assembly Embedding

Babel Obfuscator can embed multiple assemblies into the main application reducing the overall size of the
deployed assembly. The embedded assemblies are not obfuscated. If you need to protect the embedded
assemblies, you should obfuscate them first.

Embedded assemblies are stored into managed resources as compressed and encrypted data. You can
selectively compress and/or encrypt an embedded assembly by using XML rules files.

The following image shows a sample application EmployerTracker.exe after obfuscation. The referenced
DLLs EmployeeTracker.Common.dll, EmployeeTracker.EntityFramework.dll, EmployeeTracker.Fakes.dll and
EmployeeTracker.Model.dll were embedded into resources.

The embedded assemblies don’t need to be deployed; they are loaded at runtime directly from memory.
To embed an assembly inside the primary assembly, enter at the command line the --embed switch followed
by the assembly file name you want to embed:
79

babel.exe EmployeeTracker.exe --embed EmployeeTracker.Common.dll -–embed


EmployeeTracker.EntityFramework.dll --embed EmployeeTracker.Fakes.dll --embed
EmployeeTracker.Model.dll

Babel will compress and encrypt all the assemblies inside managed resources. These assemblies will be
loaded dynamically at runtime when the application will require the access to any of the types defined in the
embedded assemblies. Compression and encryption can be selectively turned on or off by using XML rules
files targeting the embed feature. Turning off compression and encryption may significantly reduce the
application startup time by improving performance respect to overall application size on disk.

For instance, if we want to encrypt the assembly EmployeeTracker.EntityFramework.dll without enabling


compression for that assembly and we want to disable both encryption and compression for
EmployeeTracker.Fakes.dll we must define the following XML rules:

babelRules.xml

<?xml version="1.0" encoding="utf-8" ?>


<Rules version="2.0">
<Rule name="embed EF" feature="embed" exclude="false">
<Target>Assembly</Target>
<Pattern>EmployeeTracker.EntityFramework.dll</Pattern>
<Properties>
<Encrypt>true</Encrypt>
<Compress>false</Compress>
</Properties>
</Rule>
<Rule name="embed fakes" feature="embed" exclude="false">
<Target>Assembly</Target>
<Pattern>EmployeeTracker.Fakes.dll</Pattern>
<Properties>
<Encrypt>false</Encrypt>
<Compress>false</Compress>
</Properties>
</Rule>
</Rules>

Finally, we have to pass the babelRules.xml at command line as follows:

babel.exe EmployeeTracker.exe --embed EmployeeTracker.Common.dll -–embed


EmployeeTracker.EntityFramework.dll --embed EmployeeTracker.Fakes.dll --embed
EmployeeTracker.Model.dll --rules babelRules.xml

We can see the encryption and compression flags for each embedded assembly at the Babel output statistics:

Embed Assemblies phase, elapsed time 00.868s


Number of embedded assemblies: 3
EmployeeTracker.Common.dll (compress=True , encrypt=True )
EmployeeTracker.EntityFramework.dll (compress=False, encrypt=True )
EmployeeTracker.Fakes.dll (compress=False, encrypt=False)
EmployeeTracker.Model.dll (compress=True , encrypt=True )

NOTE: The embedding of assemblies is not supported on all .NET platforms. To see the platforms where
assembly embedding is available, please refer to the Technology Matrix.
80

Symbols Renaming
Babel Obfuscator can rename all classes, methods, properties, events and fields to short names using custom
Unicode characters or standard ASCII codes. This will make the decompiled output more difficult to
understand and will also reduce the size of your assembly files. In this section we will see how to setup
symbols renaming, Unicode normalization and the XML map files produced during the obfuscation process.
We will also see how to rename symbols inside BAML and XAML code when obfuscating WPF and Silverlight
applications.
81

Symbols Renaming

Babel can mangle the names of namespaces, types, methods, properties, events and fields, changing their
names into a combination of alphabet character or unprintable Unicode symbols. The original symbol name is
lost and is impossible to recover the meaning of the obfuscated member. This makes code understanding and
reverse engineering extremely difficult.

You can choose from two different renaming conventions: alphabet characters or unprintable Unicode
symbols. Both minimize the number of character symbol used, reducing the overall metadata size and load
time. Babel uses the Unicode renaming schema as default, but you can switch to alphabet character set by
specifying the option --nounicode in the command line.

There are several options available to configure the Renaming process:

--types
Whether to enable type renaming.

--methods
Whether to enable method renaming.

These options can be negated to disable renaming. You might consider disabling type renaming by using the
switch --notypes or -not when debugging obfuscation issues relating to renaming.

--overloaded
This option enables overloading renaming. With overloading renaming it is possible to assign the same name
to different methods.

--virtual
Whether to enable the renaming of virtual symbols (methods, properties, events).

--flatns
The flat namespace option controls the namespace renaming. When this option is enabled, the types inside
each namespace are collapsed into the global namespace.

--xaml
This option enables the renaming of types and members used inside the XAML and BAML code.

--namelength <n>
Set the minimum name length for each symbol. Increasing this value will produce longer names more difficult
to read at the expense of an increase of the assembly size.

! NOTE
Externally-visible symbols will not be renamed by Babel unless you specify a custom rule to force that. To
increase the overall number of members obfuscated, consider lowering the visibility of your public types to
internal.
82

The following picture shows an assembly before and after name obfuscation using Unicode normalization.

Before renaming After renaming


83

Unicode Character Set

It is possible to specify the character set to use when Unicode normalization is performed.
The option --unicode accepts the optional parameter [char set] that represents a set of Unicode characters
that babel will use to generate obfuscated names. The character set can be entered specifying the comma
separated values of each Unicode character or by entering ranges of characters where the range of Unicode
values is given by the following expression:

<lower bound character> – <upper bound character>

Where <lower bound character> and <upper bound character> can be represented as hexadecimal, decimal
number or character. A mix the two forms can be used to realize a complex obfuscation Unicode character
set.

Examples:

Introducing CR (13) and LF (10) in obfuscated names

babel.exe myapp.exe –-unicode 10,13,a-z

Change to Unicode Chinese character set:

babel.exe myapp.exe --unicode 0x4E00-0x4FFF

Refer to the Unicode Character Ranges table for more customizations.


Note that when using custom character set is not always possible to generate an XML map file.

Overloaded Renaming

With overloaded renaming, the same name is used to rename methods with different signatures as long as it
is allowed by .NET Framework design rules. This makes it even more difficult for a hacker to reverse engineer
the code. Babel also renames overloads when only the method return type differs, making it impossible to
entirely decompile the code to high-level languages like C# and VB.NET, in which overloading the return type
is not permitted.

Source Overloaded Renaming


84

XAML and BAML Obfuscation

Silverlight and Windows Presentation Foundation (WPF) applications use XAML declarative markup
language, and BAML (compiled XAML), to instantiate types defined into the assembly. Babel Obfuscator
version 3.5 was one of the first obfuscators able to analyze the XAML stream in order to obfuscate Silverlight
application successfully.

Babel Obfuscator now can parse XAML and BAML resources and rename all the members referenced into
the XAML (BAML) code to produce a better obfuscation, increasing the percentage of obfuscated symbols.
This also makes your XAML code more difficult to read. Babel is also able to merge into a single assembly file
multiple assembly containing XAML (BAML) resources.

The XAML and BAML symbols renaming, is enabled by entering the --xaml switch at the command line. This
switch has additional optional parameters, as we will see later, which can be used to enhance the XAML
(BAML) obfuscation. In order to fully obfuscate all the public symbols referenced into the XAML (BAML) code,
just add to the command line the --xaml option. Babel will obfuscate all public symbols referenced into the
XAML or BAML code.

babel.exe myapp.exe --xaml

When obfuscating XAP packages, this option will force renaming of public XAML symbols defined into the
entry assembly preserving the names of the public symbols defined into referenced assemblies. Presently is
not possible to use public obfuscation driven by XML map files within a XAP package. Anyway Babel can
obfuscate each assembly separately or even merge multiple assemblies inside the XAP package into a single
obfuscated assembly.

Advanced XAML Settings


It is possible to configure additional parameters by including optional key-value pairs after the --xaml switch in
which the key is passed as a parameter with its corresponding value:

--xaml [<key>=<value>]

Admitted key value pairs are:

Key Value Default Description Available


keys On/Off Off Whether to enable renaming of static resource BAML/XAML
dictionary keys
manual On/Off Off Whether to use manual symbol renaming BAML/XAML
res On/Off Off Whether to enable renaming of resource BAML/XAML
names
strip On/Off Off Whether to strip line information/white spaces BAML/XAML
in BAML/XAML

Keys parameter when enabled will allow Babel to rename static resource key names. This will increase the
obfuscation of XAML/BAML code.

Manual symbol renaming is disabled by default. With manual symbol renaming disabled, Babel will obfuscate
all public members that are found to be referenced inside the XAML or BAML code. This is a convenient
option that minimizes the configuration required by the user to achieve a better obfuscation result. Sometimes
it is necessary to fine tune the obfuscation process by choosing carefully the public members that have to be
obfuscated. In this scenario it is better to switch on manual renaming and use quick rule or XML rules files to
target those members.

Res enables the obfuscation of the XAML/BAML resource names, making it more difficult to understand the
original purpose of a resource file.
85

Strip parameter will remove all line information from XAML/BAML code making the XAML stream difficult to
analyze.

Silverlight XAML Obfuscation

XAML renaming ensures a high percentage of symbol renaming and therefore helps improve the overall
obfuscation. Babel can remove spaces and line feeds from the XAML code reducing the size of embedded
resources. The following section shows the XAML code of a Silverlight 4.0 application before and after
obfuscation produced by Babel using XAML renaming.

MainPage.xaml content before obfuscation (2524 bytes):

<sl4:ChildWindow x:Class="SL4ObfTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:SL4ObfTest.Controls"
xmlns:sl4="clr-namespace:SL4Controls;assembly=SL4Controls" mc:Ignorable="d"
Height="400" Width="600"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<sl4:ChildWindow.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</sl4:ChildWindow.Resources>
<sl4:ChildWindow.Header>
<TextBlock Text="{Binding NoteTitle}" />
</sl4:ChildWindow.Header>
<sl4:ChildWindow.Content>
<Grid>
<controls:TiledBackground SourceUri="/SL4ObfTest;component/Images/backgroundtexture.png" Opacity="0.7" />
<Image Source="/SL4ObfTest;component/Images/backgroundshadow.png" Stretch="Fill" />
<Grid x:Name="LayoutRoot">
<TextBlock FontSize="18" FontWeight="Bold" Foreground="White"
Text="{Binding Title}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" Height="28" Width="276" Margin="6,6,316,344" />
<sl4:ChildWindow Margin="20,40,350,200">
<sl4:ChildWindow.Header>
<TextBlock Text="{Binding NoteTitle}" />
</sl4:ChildWindow.Header>
<sl4:ChildWindow.Content>
<StackPanel Orientation="Vertical" Margin="8">
<TextBlock Text="{Binding RandomQuote}" Margin="0,0,0,5" TextWrapping="Wrap" />
</StackPanel>
</sl4:ChildWindow.Content>
</sl4:ChildWindow>
<Slider Height="22" HorizontalAlignment="Left" Margin="256,40,0,0" Name="slider1" VerticalAlignment="Top"
Width="120" Maximum="100" />
<sl4:ProgressButton Height="120" Width="120" Margin="256,40,224,240" Value="{Binding ElementName=slider1,
Path=Value}"/>
</Grid>
</Grid>
</sl4:ChildWindow.Content>
</sl4:ChildWindow>

And after obfuscation (1656 bytes):

<_babel0:a x:Class="a.e" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"


xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Height="400" Width="600"
DataContext="{Binding b, Source={StaticResource a}}" xmlns:_babel0="clr-
namespace:a"><_babel0:a.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary
Source="Skins/MainSkin.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></_babel0:a.Resources><_babel0:a.a>
<TextBlock Text="{Binding b}"/></_babel0:a.a><_babel0:a.Content><Grid><_babel0:d Opacity="0.7"
_babel0:d.SourceUri="/SL4ObfTest;component/Images/backgroundtexture.png"/><Image
Source="/SL4ObfTest;component/Images/backgroundshadow.png" Stretch="Fill"/><Grid x:Name="a"><TextBlock FontSize="18"
FontWeight="Bold" Foreground="White" Text="{Binding a}" VerticalAlignment="Center" HorizontalAlignment="Center"
TextWrapping="Wrap" Height="28" Width="276" Margin="6,6,316,344"/><_babel0:a Margin="20,40,350,200"><_babel0:a.a><TextBlock
Text="{Binding b}"/></_babel0:a.a><_babel0:a.Content><StackPanel Orientation="Vertical" Margin="8"><TextBlock Text="{Binding
c}" Margin="0,0,0,5" TextWrapping="Wrap"/></StackPanel></_babel0:a.Content></_babel0:a><Slider Height="22"
HorizontalAlignment="Left" Margin="256,40,0,0" Name="b" VerticalAlignment="Top" Width="120" Maximum="100"/><_babel0:b
86

Height="120" Width="120" Margin="256,40,224,240" _babel0:b.a="{Binding ElementName=b,


Path=Value}"/></Grid></Grid></_babel0:a.Content></_babel0:a>

The options used to produce this result were:

--xaml keys=on --xaml strip=on

Note that in the obfuscated XAML code, the names of all members defined into the target assembly as well as
dictionaries names have been renamed using ASCII character set.
87

Control Flow
Obfuscation
Control flow obfuscation consists of changing the execution path of a method. Babel can make if statements
more complex to read, insert several irrelevant branches, add multiple switch instructions without changing
the behavior of the method so that is very difficult to analyze after decompilation.
88

Basic Control Flow Obfuscation

Basic control flow obfuscation is enabled with the command line option --controlflow. When enabled, Babel
changes the execution path of a method inserting several irrelevant branches so that, although the behavior of
the method is not changed, it is very difficult to analyze after decompilation. Consider the following example
that shows a method before and after control flow obfuscation.

Before control flow obfuscation After control flow obfuscation

Note: after control flow obfuscation is


performed, it is no longer possible to
reconstruct the original if-else and loop
clause for disassembly inside .NET
Reflector and only the IL listing can be
displayed.

The number of jumps inserted by Babel can be changed in a certain amount, changing the number of
iterations performed by the control flow obfuscation algorithm. This parameter is configured by the command
line option switch –iliteration <n>. Increasing the <n> value may result in an increase of the number of
branches inserted.

The <n> value does have an upper limit where the control flow cannot be altered anymore by the algorithm.
This limit depends on the method control flow structure and can be different according to the particular
method considered. This means that increasing <n> does not always result in an increased number of jumps.
89

The following graphs show an average number of jumps inserted (vertical axes) varying with the number of
iterations <n> imposed (horizontal axes) for two different assemblies. The first assembly with 1,202 methods
processed is shown on the left, whereas the second assembly with 2,596 methods processed is on the right.
The trend dash lines show that the optimum iteration value is about 3, which is also the default value.

1,202 methods scrambled 2,596 methods scrambled


16 16
14 14
12 12
10 10
8 8
6 6
4 4
2 2
0 0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Average number of jump inserted Delta Average number of jump inserted Delta

It is not recommended to increase the <n> parameter over 6, as higher values will scramble the code more,
causing the overall execution time to increase.

Enhanced Control Flow Obfuscation

The Professional and Enterprise versions have an enhanced control flow obfuscation that can scramble the
method flow graph with the insertion of nested switch instructions and make structural code changes. This
makes it more difficult to analyze the code and stop, or at least makes incorrect the representation of the
underlying high-level IL code produced by reverse engineering tools.

The enhanced control flow obfuscation is active by default when a Professional or Enterprise license is
available. In this case the controlflow option enables the generation of the enhanced control flow obfuscation
that is IL verifiable.

The user can configure additional parameters to customize the code generation by passing additional key-
value pairs to the controlflow command line option:

--controlflow [<key>=<value>]

Admitted key value pairs are:

Key Value IL Verifiable Description


goto On/Off  Whether to insert irrelevant branches
switch On/Off  Whether to enable switch scrambling
case On/Off  Whether to hide case constants
if On/Off  Whether to enable if scrambling
call On/Off  Whether to enable random calls
Value On/Off  Whether to use value encryption
token On/Off  Whether to enable emission of method tokens
underflow On/Off Whether to enable stack underflow
90

NOTE
Not all the transformations performed during control flow obfuscation are safe and makes your assembly IL
verifiable.
!

Before control flow obfuscation After enhanced control flow obfuscation (ILSpy)

Invalid Op-Codes

Invalid op-codes are byte codes not recognized by the runtime as valid MSIL instructions that Babel inserts in
each method to prevent the disassembler from decompiling the method. Invalid op-codes are not managed
properly by disassemblers like .NET Reflector, while the ILDASM disassembler can list the MSIL even with
91

the presence of invalid bytes. Therefore, it is recommended to disable the ILDASM tool with the option –
noildasm whenever possible.

The following table shows, on the left, the .NET Reflector method IL listing after obfuscation with invalid op-
codes. On the right side the same method is represented by ILDASM disassembler.

.NET Reflector C# and IL code listing ILDASM code listing

The unused instructions at offset 2, 3 and 17 that


ILDASM output in the code disassembly reflect the
inserted invalid op-codes.

The number of iterations used in the control flow algorithm as well as the invalid op-codes emission can be
configured using XML rules. There are two properties available in the control flow feature that are applied on
each method that match the rule: IlIterations and EmitInvalidOpcodes. The first is a positive integer and sets
the number of iterations for the control flow algorithm. The latter is a Boolean value and is used to enable the
emission of invalid op-codes.

Invalid op-code emission should not be performed if the obfuscated assembly targets x64 operating systems
(see Obfuscating x64 Assemblies).
92

Encryption and
Protection
Babel Obfuscator can encrypt the strings and embedded resources inside the assembly. It is also able to
encrypt the method MSIL code.
String encryption prevents an attacker for searching inside your assembly strings that could help in identifying
sensitive code. There are two ready-made string encryption algorithms available, plus there is the possibility
to write and plug inside the obfuscation process your custom string encryption algorithm.
With MSIL encryption, Babel can hide the original method code to MSIL decompilers. The encrypted methods
are decrypted at runtime only when they are accessed and stay in memory only for the time needed to the
execution and then discarded. This ensures that the method code cannot be modified in memory. The runtime
compilation also makes the method code safe against tampering. MSIL encryption is a powerful protection
tools and it is completely managed solution. Anyway, the process of decryption and runtime execution
involves reflection, and this has impact on the performance. In this section, we will see how to enable string
and resource encryption and get the best from MSIL encryption without losing too much in terms of execution
speed.
93

Code Encryption

The MSIL code encryption provided by Babel is a completely managed solution. This means that the
encrypted methods are not replaced by native code targeting a particular platform. The managed method
encryption ensures that the cross-platform nature of the .NET Framework is not compromised. Moreover, the
runtime compilation of encrypted methods allows the Just-In-Time (JIT) compiler to optimize code for the
target CPU. When a method is encrypted, its code is replaced by a call to a stub method that decrypts and
compiles a dynamic method (System.Reflection.Emit.DynamicMethod) at runtime. The original MSIL code is
compressed and encrypted into the assembly resources. Babel ensures tamper protection on the encrypted
method resource when the original assembly is strong-name signed.

When a method is encrypted, its MSIL code is replaced by a call to a stub method that ensures decryption,
runtime compilation and execution of the dynamic method. The process of decryption, compilation and
execution of the dynamic method is much slower than the original method execution, so the user must choose
carefully the list of methods to encrypt. The user can select a method to encrypt with XML rules files or by
applying on the method the System.Reflection.ObfuscationAttribute attribute. Rules files are more flexible and
allow the user to specify encryption options that are not supported by the custom attribute.
For instance, suppose you have a type named Rgb that encapsulates RGB color components, and you want
to encrypt all its methods. If the Rgb class contains few methods you can apply to each method the
System.Reflection,ObfuscationAttribute as follow:

namespace Utilities
{
public class Rgb
{
byte _r; byte _g; byte _b;

public Rgb(byte r, byte g, byte b)


{
_r = r; _g = g; _b = b;
}

public UInt32 Value


{
[Obfuscation(Feature = "msil encryption", Exclude = false)]
get
{
return ToUint32();
}
}

[Obfuscation(Feature = "msil encryption", Exclude = false)]


public UInt32 ToUint32()
{
return (UInt32)((_r << 16) | (_g << 8) | _b);
}

[Obfuscation(Feature = "msil encryption", Exclude = false)]


public static UInt32 ToUint32(Rgb rgb)
{
return rgb.ToUint32();
}
}
}
94

When the number of methods on the Rgb type becomes significantly large it is better to define a custom XML
rule:

<Rule name="Rgb" feature="msil encryption" exclude="false">


<Target>Methods</Target>
<Pattern>Utilities.Rgb::*</Pattern>
<Description>Encrypt all methods of Rgb class.</Description>
</Rule>

The above rule defined will encrypt all the methods of Rgb class.

Encrypting too many methods may result in slowing down excessively the application during execution. In this
scenario the developer can tune the number of methods that will be encrypted using custom properties
enabled for the specific feature “msil encryption”.
These custom properties are:

 MinInstructionCount
 MaxInstructionCount
 Cache
 Source

The MinInstructionCount element sets the lower limit for the number of MSIL instuctions that a method must
have to be encrypted. Conversely, the MaxInstructionCount element sets the upper limit for the number of
MSIL instuctions that a method must have to be encrypted. The Cache element contains a boolean value, and
when enabled, all the DynamicMethod attributes that match the rule are cached into memory so that the
compilation is performed only the first time the method is called. This optimization is enabled by default. The
user may decide to disable caching to ensure that the method is discarded after being used in order to free
memory resources.

<Rule name="Rgb" feature="msil encryption" exclude="false">


<Target>Methods</Target>
<Pattern>Utilities.Rgb::*</Pattern>
<Properties>
<Cache>true</Cache>
<MinInstructionCount>5</MinInstructionCount>
<MaxInstructionCount>50</MaxInstructionCount>
</Properties>
<Description>Encrypt methods of Rgb class.</Description>
</Rule>

The Source element contains a string value and its use will be described in the Customize MSIL Encryption
section.
95

The following screenshot illustrates the changes introduced by MSIL encryption:

Before MSIL encryption After MSIL encryption

Note that all the code inside the method has been replaced by a single call to an internal method that
performs decryption and code compilation of a System.Reflection.Emit.DynamicMethod object equivalent to
the original method. This encryption technique has some limitations and not all methods can be encrypted.
The methods that do not support MSIL encryption are:

• Instance constructor
• Generic methods
• Methods that use generic non-instance types
• Methods with ref or out parameters

If the user tries to obfuscate such methods, Babel will raise a warning and the method will not be encrypted.
These constraints constitute a restriction on the methods that can be encrypted, but as the method encryption
is not intended to be used extensively on the target assembly, this limitation is not very important. The
developer should encrypt only highly sensitive methods. A few examples of methods you may want to encrypt
are:

• License file parsing


• Activation key validation
• Proprietary algorithms

Most of the time, these methods can be arranged so that Babel can successfully perform MSIL encryption.
Note that since Miscrosoft provides different implementation of DynamicMethod depending on the .NET
Framework technology, MSIL encryption is supported only on .NET Framework 2.0 and later (see Technology
Matrix).
96

String Encryption

Babel Obfuscator can encrypt so-called User Strings embedded into a managed assembly.
User Strings are all the strings found in the metadata #US heap that are referenced in the user code.
Basically, all the strings contained into the #US heap are those in-lined into the code and the ones defined as
static readonly in C# language or Shared ReadOnly in VB.

Babel Obfuscator has two different string encryption algorithms: the xor and the hash algorithms. Each
algorithm can be specified at the command line by using the following syntax:

--string [algorithm]

Where [algorithm] is an optional parameter that can be either xor or hash. If the user does not specify the
[algorithm] at command line, Babel Obfuscator will choose the best algorithm available according to the target
platform (.NET Framework, XNA, Silverlight or Windows RT) and the available license. Note that the hash
algorithm is not available on all .NET platforms. Please take a look at the Technology Matrix to know where
hash algorithm can be used.

! NOTE
Strings defined as const, cannot be encrypted by Babel Obfuscator because they are baked into the
metadata #Blob heap and initialized directly by the CLR. To encrypt const string, you can try to convert
them to static readonly (C#) or Shared ReadOnly (VB) ex:

public const string Connection = "Server=myServerAddress;Database=myDB;...";

public static readonly string Connection = "Server=myServerAddress;Database=myDB;...";

XOR Algorithm
The xor algorithm is the simplest one and consists of xor-ed in lined string characters with a random integer
key. This method is not tamper proof.
The xor method encryption is shown in the following screenshots. The image on the left shows the original
code disassembly with a string referenced by the instantiation of the OpenFileDialog class, while the image on
the right shows the same code after xor string encryption.

Code Xor string encryption

HASH Algorithm
The hash algorithm is based on hash tables addressed by integer keys. This algorithm performs compression
and encryption of string data to reduce the overall file size. This algorithm also ensures tamper-proof
protection.
The following picture shows hash string encryption algorithm code disassembly:
97

Code Hash string encryption

Custom String Encryption

With custom string encryption, the user must define inside the target assembly two methods: one to encrypt
strings EncryptString, and one to decrypt encrypted strings DecryptString. The prototype for these two
methods is the same: they both accept a string parameter and return their encrypted or decrypted string
value:

/// <summary>
/// Encrypt a string.
/// </summary>
/// <param name="text">The string to encrypt.</param>
/// <returns>The encrypted string.</returns>
[Obfuscation(Feature = "string encryption encrypt method")]
internal static string EncryptString(string text)
{
// Encrypt text string and return the encrypted string object.
return ...;
}

/// <summary>
/// Decrypt an encrypted string.
/// </summary>
/// <param name="text">The encrypted string.</param>
/// <returns>The decrypted string.</returns>
[Obfuscation(Feature = "string encryption decrypt method")]
internal static string DecryptString(string text)
{
// Decrypt text string and return the decrypted string object.
return ...;
}

The EncryptString and DecryptString methods must be decorated with the


System.Reflection.ObfuscationAttribute indicating the appropriate feature name to let Babel know the specific
purpose of each method.

Babel will search for these two methods and use them when encrypting strings. At the end of the string
encryption phase, Babel will remove the EncryptString method because it will not be necessary at runtime.
Because babel.exe need to call the EncryptString method during obfuscation, the Custom String Encryption is
available only when obfuscating applications targeting the .NET Framework platform.
Custom string encryption is also available using Plugins.

Inline Values and Array Encryption

Constant values and arrays declared inline may contain sensitive information such as data encryption keys
that the user wants to hide to disassembler. Babel Obfuscator can encrypt constant values and arrays inside a
method, securing sensitive information and providing an extra protection layer.
98

The encryption of values and arrays is disabled by default and can be enabled by entering at the command
line the switch valueencryption:

babel.exe myapp.exe --valueencryption

The user can configure additional parameters passing additional key-value pairs to the valueencryption
command line option:

--valueencryption [<key>=<value>]

Admitted key value pairs:

Key Value Description


int32 On/Off Whether to encrypt Int32 values
int64 On/Off Whether to encrypt Int64 values
single On/Off Whether to encrypt Single values
double On/Off Whether to encrypt Double values
array On/Off Whether to encrypt Arrays

The following table shows a method using inline values and arrays before and after value encryption.

Before value encryption After value encryption

Babel can encrypt arrays of different types.

As for all other Babel obfuscator features, value encryption can be controlled by XML rules. It is possible to
encrypt values and arrays only on those methods that match XML rule filters.

The feature name to use is: “value encryption”:

<Rule name="reduce value encrypt1" feature="value encryption" exclude="true">


<Target>Methods</Target>
99

<Pattern>*</Pattern>
<HasAttribute
onEnclosingType="false">System.Runtime.CompilerServices.CompilerGeneratedAttribute,System.Dia
gnostics.DebuggerHiddenAttribute</HasAttribute>
<Description>Do not encrypt values in compiler generated methods.</Description>
</Rule>

Babel will show at the end of the obfuscation process, inline values and arrays encryption statistics:

Encrypt Values phase, elapsed time 00.276s


System.Int32: 2863
System.Int64: 0
System.Single: 37
System.Double: 38
System.Array: 5

Resource Encryption

Babel can compress and encrypt embedded resources to protect your resources and also to reduce the
overall assembly size. The encrypted resources are loaded at runtime when they are eventually needed.
The following pictures show an assembly with embedded resource before and after resource encryption.

Before resource encryption After resource encryption

Resource encryption can be used to hide WPF resources from being inspected by tools like .NET Reflector.
Please refer to the Technology Matrix to see where the resource encryption feature is available.

Additionally, you can configure resource encryption to compress original resources. You can enable resource
compression in the obfuscation Settings panel:

At command line, you can enable resource compression with the following option:

--resource compress=true

To know all the options available with the resourceencryption switch you can enter:
100

> babel.exe --help resource

resourceencryption (noresourceencryption, no-resourceencryption, resources)


usage: --[no]resourceencryption
Enable ([no]disable) embedded resource encryption (default: disabled)

When enabled, all the embedded resources will be encrypted.


value pair <key>=<value> can optionally be entered to enable or disable
additional features:

encrypt=[on/off] Whether to encrypt resources (on)


compress=[on/off] Whether to compress resources (off)

Note that the compression of resources can save disk space at the expense of an increase in the startup time
due to the resources decompression.
101

Dynamic Proxy Calls

With dynamic proxy calls it is possible to hide all the calls to external and internal methods, inside delegate
types dynamically built at runtime. To enable dynamic proxy calls generation, use the switch –proxy at the
Babel command line. When enabled, this option will configure Babel to create proxies for externals and
internals calls. It is also possible to pass an optional parameter to force the generation only for internal or
external calls:

babel myapp.exe –-proxy internal

Will generate proxies for only internal calls, while:

babel myapp.exe –-proxy all

Generates calls to internal and external methods.


The following table shows a method where internal and external calls were obfuscated using dynamic proxies.

Before dynamic proxy call obfuscation After dynamic proxy call obfuscation

The statistics at the end of the obfuscation process will show the number of delegate types generated and the
number of calls routed through proxies.

Dynamic Proxy Call phase, elapsed time 03.354s


Dynamic proxy call: external
Number of delegate types generated: 2334
Number of proxy calls: 15876

Dynamic proxies are built by means of dynamic methods, so they can slow down the startup time of your
application. Presently dynamic proxies are supported only by .NET Framework 2.0/3.x/4.0 and Silverlight.
To see the platforms where Dynamic Proxy is available, please refers to the Technology Matrix.
102

Tampering Detection

The .NET Framework can detect an application has been tampered with, when the assembly has been
signed. Babel Obfuscator can add an extra layer that will allow you to execute custom logic in case the
application has been tampered.

To enable tampering detection, add to the babel command line the following switch.

babel.exe myapp.exe --tampering

If you are using the Babel task, add the TamperindDetection attribute:

<Babel InputFile="myapp.exe" TamperingDetection="true" … />

When Babel Obfuscator tampering-detection is activated, the obfuscated assembly will check if the assembly
has been tampered with, and if it so, the application will be terminated. You can configure tampering
detection, to not terminate the application but call a custom method inside your assembly that will properly
handle the tampering.

Configure tampering detection to call a custom method is easy. Just choose a type inside your assembly and
add the following method:

[Obfuscation(Feature = "on tampering detected method")]


static void OnTamperingDetected()
{
}

For example, you can define the following class:

class CutomTampering
{
public static bool HasBeenTampered { get; internal set; }

[Obfuscation(Feature = "on tampering detected method")]


static void OnTamperingDetected()
{
HasBeenTampered = true;
}
}

Somewhere in your application you can do:

if (CutomTampering.HasBeenTampered)
{
// Application tampered
// Do somethig bad!
}

The tampering detection will be checked at runtime when accessing for the first time the HasBeenTampered
property.

You can add the OnTamperingDetected method to any existing type inside your application.
Please ensure that the type you have chosen is used somewhere inside the application, otherwise the
tampering detection code will not be called. Note that the tampering detection will be checked the first time the
application uses the type in which you added the OnTamperingDetected method.

We encourage you to customize the tampering detection handling by adding the OnTamperingDetected
method to your code. You should handle the tamper detection by not terminating the application suddenly
103

because this can be tracked and removed easily. Better to set a hidden flag that will be checked during the
execution so that in the event the application has been tampered with, incorrect results will be generated.

Debugging Protection

Babel Obfuscator can inject into an assembly anti-debugging code so that if the assembly is run under a
debugger, the application will be terminated. Instead of terminating the application, you can setup your custom
logic that will be executed when a debugger is attached.

To enable anti-debugging protection, add to the babel command line the following switch.

babel.exe myapp.exe --antidebugging

If you are using the Babel task, add the DebuggingProtection attribute:

<Babel InputFile="$(AppName).exe" DebuggingProtection="true" … />

To configure an action that will be called when the application is debugged just add the following method to an
existing class inside your assembly:

[Obfuscation(Feature = "on debugger detected method")]


static void OnDebuggerDetected()
{
// This method is called if the application is running under a debugger.
// The code inside this method must be thread safe as it is called
// by different runnng threads.
}

Then enable anti-debugging protection.

Note that the OnDebuggerDetected can be called multiple times and by different threads when a debugger is
detected.
104

Code Generation
Babel performs metadata optimizations during the obfuscation process. These optimizations aim to make the
code faster and reduce the assembly size making even the decompiled code harder to read. In this section,
we will see how Babel can improve the generated code and how these optimizations affect the code
readability.
105

Dead Code Removal

Babel can remove code that will never be executed at runtime. It may consist of methods, properties, fields
and even types. This will reduce the size of your assembly and improve loading time. Dead code removal can
be enabled at command line using the --deadcode switch:

babel.exe myapp.exe --deadcode

The removal of unused symbols can be controlled by using XML rules that target the “dead code” feature. The
following XML rule prevents the removing of all symbols in the Utilities namespace.

<Rule name="remove1" feature="dead code" exclude="true">


<Pattern isRegEx="true">
<![CDATA[
(Utilities.*)
]]>
</Pattern>
<Description>Do not remove symbols in Utilities namespace</Description>
</Rule>

You can change the verbosity of Babel output and see the symbols that have been removed:

babel.exe myapp.exe –deadcode –v3 –stat

Removing Unused Code...


System.Boolean get_IsPinned()
System.Boolean get_IsEmpty()
System.Void SendMessage()
MyApp.Message FormatHeader()
MyApp.Address ParseAddress(System.String)
System.Generic.Collection`1<MyApp.Message> get_PendingMessages()
System.Boolean get_HasHeader()
System.String MakeRelativePath(System.String,System.String)
MyApp.IMessage
MyApp.Message

In the obfuscation statistics Babel prints a summary of all the symbols removed during the obfuscation
process.

Dead Code Removal phase, elapsed time 01.453s


Removed types: 217
Removed methods: 448
Removed properties: 89
Removed events: 3
Removed fields: 1092

Metadata Optimizations

Besides dead code removal Babel provides metadata optimizations. Metadata optimizations aiming at
reducing the information contained in the metadata thus improving performance and lessening loading time.

Automatic Class Sealing


Classes that are not used as base classes in an inheritance chain can be sealed. When the JIT compiler sees
a call to a virtual method using a sealed type, it can produce more efficient code by calling the method non-
virtually.
106

This optimization can be enabled from the command line using the switch --seal and it affects all non-public
types defined into the target assembly.

babel.exe myapp.exe --seal

By defining an XML rule it is possible to selectively exclude the automatic class sealing for a subset of types
that match a regular expression:

<Rule name="seal classes" feature="optimizations" exclude="false">


<Pattern>Utilities.*</Pattern>
<Properties>
<ClassSealing>false</ClassSealing>
</Properties>
</Rule>

Note that we set the exclude attribute to false, otherwise all the optimizations included automatic class sealing
would have been disabled.

Removing of Unwanted Attributes


Most of the times, the compiler-generated code contains attributes that can be removed without affecting the
behavior of the application during execution. Babel can remove any attribute applied to a defined symbol
during the optimization process. For instance, it is possible to remove attributes that are not useful to the
application itself like: CompilerGeneratedAttribute or DebuggerDisplayAttribute from the members defined into
the assembly. This will save bytes in the obfuscated target and will also avoid distinguishing between the
compiler generated and the user code.

This optimization can be enabled by entering at the command line the switch cleanattrs:

babel.exe myapp.exe --cleanattrs

The list of the attributes that will be removed is stored into the babel.exe.config file. To see the attributes that
are actually configured to be removed you can enter:

babel.exe –-help cleanattrs

cleanattrs (nocleanattrs, no-cleanattrs, ca)


usage: --[no]cleanattrs <regex>
Enable ([no]disable) removal of unwanted attributes (alias: --ca) (default: disabled)

Unwanted attributes:

\[mscorlib\]System.Runtime.CompilerServices.CompilerGeneratedAttribute
\[mscorlib\]System.Diagnostics.DebuggerDisplayAttribute
\[mscorlib\]System.Diagnostics.DebuggerBrowsableAttribute
\[mscorlib\]System.Diagnostics.DebuggerNonUserCodeAttribute
\[mscorlib\]System.Diagnostics.DebuggerHiddenAttribute
\[mscorlib\]System.Diagnostics.DebuggerStepThroughAttribute

Optionally a regular expression can be specified to match the unwanted attribute type full name:

babel.exe myapp.exe --cleanattrs System.Diagnostics.*Attribute

This will remove all custom attribute types defined in the System.Diagnostics namespace.
107

A predefined list of unwanted attributes is stored in the babel.exe.config configuration section at the element
UnwantedAttributes. The element is a string collection in which each item is given by the qualified attribute
type name:

<setting name="CleanupUnwantedAttributes" serializeAs="String">


<value>True</value>
</setting>
<setting name="UnwantedAttributes" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>\[mscorlib\]System.Runtime.CompilerServices.CompilerGeneratedAttribute
</string>
<string>\[mscorlib\]System.Diagnostics.DebuggerDisplayAtrribute</string>
</ArrayOfString>
</value>
</setting>

Each string element of the UnwantedAttributes collection, defines a regular expression that match the custom
attribute full type name in the following form:

[assembly name]FullTypeName

So, for instance the simplest regular expression that match DebuggerStepThroughAttribute is the following:

\[mscorlib\]System.Diagnostics.DebuggerStepThroughAttribute

Note that we have to use the escape ‘\’ character before the open and close brackets since these are
reserved to regular expression syntax. The assembly name is not mandatory and can be omitted.

An XML rule property is also available to finely configure attributes removal for all members matching a given
regular expression similar to the one described for automatic class sealing:

<Rule name="unwanted attributes" feature="optimizations" exclude="false">


<Pattern>Utilities.*</Pattern>
<Properties>
<UnwantedAttributes>false</UnwantedAttributes>
</Properties>
</Rule>

System.Enum Types Removal


Babel can remove, whenever possible, System.Enum types defined into the target assembly by replacing their
fields with the relative values. This optimization saves disk space and also makes the disassembled code
more difficult to understand due to the use of constants instead of field names.

To enable the removal of enumeration types, enter at the command line the option enumremoval:

babel.exe myapp.exe --enumremoval

The optimization feature provides the EnumRemoval Boolean property that can be used to selectively exclude
or include the enumeration types.

<Rule name="enum removal" feature="optimizations" exclude="false">


<Pattern>Utilities.*</Pattern>
<Properties>
<EnumRemoval>false</EnumRemoval>
</Properties>
108

</Rule>

Disgregate Removal
This optimization performs the removal of properties and events information from the respective metadata
tables. The properties and events removed, will have their get_ and set_ or add_ and remove_ methods
converted to standard methods. This optimization reduces the metadata size and when combined with
renaming produce a better obfuscation making more difficult to reconstruct the original property.

To enable properties and event metadata removal enter at command line:

babel.exe myapp.exe --disgregateremoval

You can selectively enable or disable properties and events disgregation using XML rule as follow:

<Rule name="disgregate removal" feature="optimizations" exclude="false">


<Pattern>Utilities.*</Pattern>
<Properties>
<DisgregateRemoval>false</DisgregateRemoval>
</Properties>
</Rule>

Code Optimizations

Inline Expansion
Inline expansion will allow to substitute the call to a method with the instructions in its body inline thereby
saving the overhead of function invocation.

To enable inline expansion you need to target the methods that should be expanded inline.
This can be done using the System.Reflection.ObfuscationAttribute directly on the method:

[Obfuscation(Feature = "inline", Exclude = false)]


public void Info(string message)
{

Or by adding an obfuscation rule to the method or type you want to be expanded:


109

<Rule name="inline1"
feature="optimizations" exclude="false">

<Pattern>AcmeDataMining.Logger::Info(String) : Void</Pattern>
<Properties>
<Inline>True</Inline>
</Properties>
</Rule>

Then to enable inline expansion processing, you have to check the Inline Expansion checkbox in the
Optimization panel:

Or enter at command line the global switch --inlineexpansion:

babel.exe myapp.exe --inlineexpansion --stat

The obfuscation statistics will show the number of inline methods and how many (expansion) occurred:

Optimization phase, elapsed time 00.270s


Sealed types: 0
Inlined methods (expanded): 266 (736)
110

Code Instrumentation
Code instrumentation allows injection of code into an assembly by hooking the entry and exit of any method or
property or the catch of any exception. This is typically used to intercept function calls to either monitor the
execution or perform custom exception management.
In order to hook the entry/exit points of a method, user must provide the methods to be called when the
execution path reach either the entry or exit of any method. It is also possible to intercept the occurrence of
any managed exception and forward the execution to custom methods to handle the occurrence of the error.
The practical uses of instrumentation are many. Because the code is instrumented at post-build, the
developer can flavor the application with enhanced logging functionalities, custom exception management or
code profiling, with little effort. It is even possible to implement a custom protection based on instrumented
code and let Babel to manage the injection of protection routines.
111

Activating Instrumentation
The command switches related to code instrumentation can be found under the Code Generation section at
Babel help menu. Basically, there are three options available: addreference <assembly>, [no]instrument
[regex] and [no]emptymethods. The most important option is instrument [regex]; we will see the description of
the other commands later in this chapter. With this option, you can establish the set of methods that have to
be instrumented. The command works like msilencryption command and it accepts an optional regular
expression used to catch all the methods that are matching the regular expression given. Because this
command can be entered multiple times at the command line, it is possible to build a complex set of methods
coming from different types or namespaces. The command regular expression is optional and if omitted will
lead the search for methods to be instrumented to the rules defined in XML rules files. In case there are no
XML rules files and no regular expression specified, the set of method to instrument will be empty and no
methods will be instrumented.

Once the set of methods to instrument is established there is another fundamental thing that Babel needs to
know i.e. the stub methods. These methods are called when the entry and exit point of each method is
reached or whenever a managed exception is thrown.

Basically, there are three stub methods that can be defined: the first is called when the entry point is reached
and it has the following signature:

public static void OnEntry(object instance, MethodBase method, params object[] args)
{
}

The object instance parameter contains the reference to the calling method object or null in case the method
is static. The MethodBase method parameter provides information about the instrumented method, while the
params object[] args will represent the method arguments object array.

The second stub is called when a method exit point is reached and it has the following signature:

public static void OnExit(object instance, MethodBase method)


{
}

Where instance and method parameters have the same meaning described in the OnEntry method.

The last stub is called whenever a managed exception is thrown inside a method end it has the following
signature:

public static bool OnException(object instance, MethodBase method, Exception e)


{
}

Note that the Exception e parameter will contain the instance of the exception caught. This will be null in case
the type of the catch clause has not been specified.

To let Babel know about these methods the user can decorate each method with the appropriate
System.Reflection.ObfuscationAttribute attribute using the Feature string constructor parameter to target the
specific method definition:

[Obfuscation(Feature = "instrumentation on entry method")]


public static void OnEntry(object instance, MethodBase method, params object[] args)

[Obfuscation(Feature = "instrumentation on exit method")]


public static void OnExit(object instance, MethodBase method)

[Obfuscation(Feature = "instrumentation on exception method")]


public static bool OnException(object instance, MethodBase method, Exception e)
112

The name given to the methods is not relevant; while the method signature (i.e. the number and order of
method parameter as well as its return type) should be respected to ensure that Babel recognizes the
methods as valid stub. Note that the presence of the OnEntry stub method is always required in conjunction
with one of the OnExit or OnException methods.

Wherever is not possible to use the System.Reflection.ObfuscationAttribute attribute to indicate the stubs
methods, XML rule files should be used. For example, the following XML rule file can be used to declare the
three method stubs defined into the Tracer class:

<?xml version="1.0" encoding="utf-8" ?>


<Rules version="2.0">
<Rule name="entry" feature="instrumentation on entry method" exclude="false">
<Target>Methods</Target>
<Pattern>SimpleTracer.Tracer.OnEntry*</Pattern>
</Rule>
<Rule name="exit" feature="instrumentation on exit method" exclude="false">
<Target>Methods</Target>
<Pattern>SimpleTracer.Tracer.OnExit*</Pattern>
</Rule>
<Rule name="exception" feature="instrumentation on exception method" exclude="false">
<Target>Methods</Target>
<Pattern>SimpleTracer.Tracer.OnException*</Pattern>
</Rule>
</Rules>

Simple Tracing Walkthrough

This walkthrough give step-by-step instructions to build a simple tracing and logging component that will be
used by Babel to instrument an application. This makes it a good place to start learning about using Babel
code instrumentation. For this walkthrough, we will use Visual Studio 2010.

Creating SimpleTrace Project


To create the SimpleTrace class library and Trace component

1. From the File menu, select New and then Project to open the New Project dialog. Select the Class
Library project template from the list of Visual C# project types, and enter SimpleTrace in the Name
box.
2. In Solution Explorer, right-click Class1.cs and select Rename from the shortcut menu.
3. Enter the new name Tracer.cs and press enter.
Visual Studio will display a message box asking to rename all references to the code element
Class1. Press Yes.
4. In Solution Explorer, double click Traces.cs to open the Tracer class definition into the Code
Editor.
5. Add the following using statement to the list of using statements at the top of the Code Editor for
Tracer.

using System.Reflection;

6. Apply the following attribute to the Tracer class:

[Obfuscation(Feature = "instrumentation", Exclude = true, ApplyToMembers = true)]


public class Tracer
{
}
113

7. Add the following code inside the Tracer class definition:

public static readonly Tracer Instance = new Tracer();

private Tracer()
{
}

private void OnMethodEntry(object instance, MethodBase method, params object[] args)


{
System.Diagnostics.Trace.WriteLine(String.Format("{0}::{1}",
method.DeclaringType.FullName, BuildMethodSignature(method, args)));

System.Diagnostics.Trace.Indent();
}

private bool OnMethodException(object instance, MethodBase method, Exception e)


{
// Note that the Exception e parameter can be null
// in case the catch type has not been specified
System.Diagnostics.Trace.TraceError("Method {0} throws an exception: {1}",
method.Name, e);

// true = Rethrow the exception


return true;
}

private void OnMethodExit(object instance, MethodBase method)


{
System.Diagnostics.Trace.Unindent();
}

private string BuildMethodSignature(MethodBase method, object[] args)


{
StringBuilder sb = new StringBuilder();
sb.Append(method.Name);
sb.Append('(');
ParameterInfo[] parameters = method.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
if (i > 0)
sb.Append(", ");

ParameterInfo paramInfo = parameters[i];


sb.Append(paramInfo.ParameterType.FullName);

try
{
if (i < args.Length)
{
object arg = args[i];
sb.AppendFormat("={0}", arg == null ? "null" : arg.ToString());
}
}
catch (Exception e)
{
System.Diagnostics.Trace.TraceError(e.ToString());
System.Diagnostics.Trace.TraceError(String.Format("Parameter {0}={1}", i,
paramInfo.ParameterType.FullName));
}
}
114

sb.Append(')');
return sb.ToString();
}

Adding stub methods and building the project


To add the stub OnEntry, OnException and OnExit methods

1. Locate the constructor for Tracer (private Tracer()), and add the following code after the method
closing bracket.

[Obfuscation(Feature = "instrumentation on entry method")]


public static void OnEntry(object instance, MethodBase method, params object[] args)
{
Tracer.Instance.OnMethodEntry(instance, method, args);
}

[Obfuscation(Feature = "instrumentation on exception method")]


public static bool OnException(object instance, MethodBase method, Exception e)
{
return Tracer.Instance.OnMethodException(instance, method, e);
}

[Obfuscation(Feature = "instrumentation on exit method")]


public static void OnExit(object instance, MethodBase method)
{
Tracer.Instance.OnMethodExit(instance, method);
}

2. Press Ctrl+Shift+B to build the project.

Creating an Obfuscation Test Project


To create a simple obfuscation test Console application

1. In Solution Explorer, right-click the Solution ‘SimpleTrace’ node and select Add an then New
Project from the shortcut menu.
2. Select the Console Application project template from the list of Visual C# project types, and enter
TraceClient in the Name box.
3. In Solution Explorer, double click Program.cs to open the Program class definition into the Code
Editor.
4. Add the following code inside the Program class after the Main() method definition:

private static long Factorial(long val)


{
return val <= 1 ? 1 : val * Factorial(val - 1);
}

5. Inside the Main() method definition add the following code:

for (int i = 5; i >= 0 ; i--)


{
Console.WriteLine("1000 / ({0}! - 1) = {1}", i, (1000 / (Factorial(i) - 1)));
}

6. In Solution Explorer right-click TraceClient project node and select Add then New Item from the
shortcut menu.
115

7. In the Add New Item dialog box, select Application Configuration File. Click Add to create the
App.config file.
8. Double click the App.config file to open in the Code Editor and insert the following XML fragment
inside the configuration element node:

<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="myListener" type="System.Diagnostics.TextWriterTraceListener"
initializeData="tracer.txt" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>

9. Press Ctrl+Shift+B to build the project.

Instrumenting the TestClient Application


To instrument the TestClient application using the trace functionalities implemented into SimpleTrace
component.

1. Copy the SimpleTrace.dll component to the TestClient build output folder (bin\Debug)
2. Open a DOS command window and set the current directory to the TestClient project output folder.
3. Enter the following Babel command line:

babel.exe @ TraceClient.exe --instrument .* --addreference SimpleTrace.dll

4. Copy the SimpleTrace.dll component and the TraceClient.exe.config configuration file to the
BabelOut folder.
5. Enter at the command line the following command:

BabelOut\TraceClient.exe

The TraceClient application should print the following:

1000 / (5! - 1) = 8
1000 / (4! - 1) = 43
1000 / (3! - 1) = 200
1000 / (2! - 1) = 1000

Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.


at TraceClient.Program.Main(String[] args)

The instrumented TraceClient.exe should have generated the call trace ASCII file tracer.txt in the BabelOut
folder containing the following lines:

TraceClient.Program::Main(System.String[]=System.String[])
TraceClient.Program::Factorial(System.Int64=5)
TraceClient.Program::Factorial(System.Int64=4)
TraceClient.Program::Factorial(System.Int64=3)
TraceClient.Program::Factorial(System.Int64=2)
TraceClient.Program::Factorial(System.Int64=1)
TraceClient.Program::Factorial(System.Int64=4)
TraceClient.Program::Factorial(System.Int64=3)
TraceClient.Program::Factorial(System.Int64=2)
TraceClient.Program::Factorial(System.Int64=1)
TraceClient.Program::Factorial(System.Int64=3)
TraceClient.Program::Factorial(System.Int64=2)
TraceClient.Program::Factorial(System.Int64=1)
TraceClient.Program::Factorial(System.Int64=2)
116

TraceClient.Program::Factorial(System.Int64=1)
TraceClient.Program::Factorial(System.Int64=1)
TraceClient.exe Error: 0 : Method Main throws an exception:
System.DivideByZeroException: Attempted to divide by zero.
at TraceClient.Program.Main(String[] args)

Note that the ouput shows the trace of the exception thrown by the last call to the Factorial method.
117

MSBuild Task
Babel Obfuscator comes with support for the MSBuild tool by means of a custom task that performs the
obfuscation launching the babel.exe command with options read from task properties. The Babel MSBuild
task is defined in the assembly Babel.Build.dll located in the MSBuild folder under the program installation
directory (typically: C:\Program Files\Babel). The same assembly is installed under the system Global
Assembly Cache.
118

MSBuild Babel Task

Babel task can be added to any MSBuild project by inserting the appropriate UsingTask element into the
MSBuild project xml file:

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7" />

If you want to use a different version of the Babel task you can do so using the following syntax:

<UsingTask TaskName="Lic" AssemblyFile="<Full path to Babel.Build.dll>" />

Where AssemblyFile attribute specifies the full path to the Babel.Build.dll you want to use in your build
project.

Consider the following very simple C# project made by one executable assembly that references one DLL
library. We’ll use this sample to describe how to make an MSBuild project using the Babel task.

The main assembly HelloWorld.exe is a console application that makes a call to a static method
Hello.ToConsole() defined in the assembly HelloLib.dll:

Main.cs
using System;
using HelloLib;

namespace HelloApp
{
class Program
{
public static void Main(string[] args)
{
Hello.ToConsole();
}
}
}

HelloLib.cs
using System;

namespace HelloLib
{
public class Hello
{
public static void ToConsole()
{
Console.WriteLine("Hello");
}
}
}

First, we need to create an MSBuild project file: Hello.proj to build the Main.cs and HelloLib.cs source files into
their respective assemblies and include the UsingTask element to reference the Babel task.

<?xml version="1.0" encoding="UTF-8"?>


<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7"/>
119

</Project>

To tell MSBuild to compile the HelloLib.cs file into HelloLib.dll assembly, we define a Task that calls the C#
compiler (CSC) on HelloLib.cs and specify the file format library for the output file using the TargetType
attribute:

<?xml version="1.0" encoding="UTF-8"?>


<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7"/>

<ItemGroup>
<CSLibFile Include="HelloLib.cs"/>
</ItemGroup>

<Target Name="HelloLib">
<Message Text="Building $(TargetFile)..."/>
<CSC Sources="@(CSLibFile)"
WarningLevel="$(WarningLevel)"
TargetType="library">
</CSC>
</Target>
</Project>

Now we need to define another Target that compiles the file Main.cs and builds the HelloWorld.exe
application using as reference the HelloLib.dll library:

<?xml version="1.0" encoding="UTF-8"?>


<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7"/>

<PropertyGroup>
<AppName>HelloWorld</AppName>
<LibName>HelloLib</LibName>
</PropertyGroup>

<ItemGroup>
<CSLibFile Include="HelloLib.cs"/>
</ItemGroup>

<ItemGroup>
<CSFile Include="Main.cs"/>
</ItemGroup>

<Target Name="HelloLib">
<Message Text="Building $(LibName)..."/>
<CSC Sources="@(CSLibFile)"
WarningLevel="$(WarningLevel)"
TargetType="library">
</CSC>
</Target>

<Target Name="Build" DependsOnTargets="HelloLib">


<Message Text="Building $(Appname)..."/>
<CSC Sources="@(CSFile)"
References="$(LibName).dll"
WarningLevel="$(WarningLevel)"
120

OutputAssembly="$(AppName).exe">
</CSC>
</Target>
</Project>

Because the project file contains multiple targets, we need to specify the DefaultTargets attribute into the
Project element so that MSBuild knows to execute the Build target first. Note that the Build target depends on
the HelloLib target because the referenced assembly needs to be available when the Main.cs file is compiled.
We can build the HelloWorld.exe application by entering into the command shell the command:

msbuild.exe Hello.proj

We now have the HelloWorld.exe application and the HelloLib.dll, but we didn’t use the Babel task yet.
Suppose that we want to obfuscate only the HelloWorld.exe assembly. This can be easily achieved by adding
to the Build target the Babel task declaration:

<Target Name="Build" DependsOnTargets="HelloLib">


<Message Text="Building $(Appname)..."/>
<CSC Sources="@(CSFile)"
References="$(LibName).dll"
WarningLevel="$(WarningLevel)"
OutputAssembly="$(AppName).exe">
</CSC>

<Babel InputFile="$(AppName).exe"/>

</Target>

The only task attribute that we need to specify is the InputFile attribute. This attribute is mandatory and is
equivalent to specifying the primary assembly source into the babel.exe command line. The task so defined
will start babel.exe to obfuscate the HelloWorld.exe primary assembly using the default options. The
obfuscated assembly will be saved into the BabelOut folder.

The Babel task can locate the babel.exe tool under the system “Program Files” folder when installed into the
standard Babel directory. If the Babel setup was performed to install the program under a directory with a
different name, the Babel task will not be able to find the babel.exe executable and the build process will
terminate with an error. In this scenario, we need to specify the Babel installation directory as input to the
Babel task by using the attribute ToolPath:

<Babel ToolPath="C:\Program Files\Babel Obfuscator" InputFile="$(AppName).exe"/>

You can add more attributes to customize the obfuscation process. For instance, if you want to save the
obfuscated assembly with a different name you can add the OutputFile attribute with the name of the
obfuscated executable:

<Babel InputFile="$(AppName).exe"
OutputFile="$(AppName)_babel.exe"/>

The obfuscated assembly will be saved in the same folder as the primary source with the name:
HelloWorld_babel.exe. You can also change the encryption string algorithm used when Babel encrypt strings
by specifying the StringEncryptionAlgorithm attribute:

<Babel InputFile="$(AppName).exe"
StringEncryptionAlgorithm="hash"
OutputFile="$(AppName)_babel.exe"/>

Or you can instruct Babel task to merge the referenced assembly HelloLib.dll into the primary assembly by
adding the MergeAssemblies attribute:

<Babel InputFile="$(AppName).exe"
MergeAssemblies="$(LibName).dll"
121

Internalize="true"
StringEncryptionAlgorithm="hash"
OutputFile="$(AppName)_babel.exe"/>

The Internalize attribute changes the visibility of Hello class so that it will be visible only to types defined
internally to the merged assembly. This ensures that all the internalized types can be subsequently
obfuscated.
If you want to merge multiple libraries into the primary assembly, you need to specify the names of the
libraries separated by a semicolon:

MergeAssemblies="$(LibName1).dll;$(LibName2).dll"

Now suppose that you want to encrypt all the methods defined in the HelloLib.dll assembly. Usually to do this
you would need to define a rules XML file to target the msil encryption feature and pass to the babel.exe
command line the msilencrypt option. With a Babel task you can do the same by adding two attributes: the
first, RulesFiles, defines a list of XML rules files to use as input. The second, MsilEncryption, tells babel.exe to
run the MSIL encryption phase.

<Babel InputFile="$(AppName).exe"
MergeAssemblies="$(LibName).dll"
Internalize="true"
StringEncryptionAlgorithm="hash"
RulesFiles="babelRules.xml"
MsilEncryption="true"
OutputFile="$(AppName)_babel.exe"/>

The babelRules.xml file is defined as follow:

<?xml version="1.0" encoding="utf-8"?>


<Rules version="2.0">
<Rule name="encrypt" feature="msil encryption" exclude="false">
<Target>Methods</Target>
<Pattern>HelloLib.*</Pattern>
<Properties>
<Cache>true</Cache>
</Properties>
<Description>Encrypt HelloLib methods.</Description>
</Rule>
</Rules>

Babel MSBuild Project Files

Babel Obfuscator can generate an MSBuild project file containing the necessary build instruction to perform
the obfuscation configured at the command line. This eases the setup of the obfuscation process and also
provides a handy way to generate the MSBuild Babel task element to insert inside a Visual Studio project. For
instance, the following command line:

babel myapp.exe myapp.Core.dll myapp.Data.dll myapp.GUI.dll myapp.Resources.dll --out


myapp.exe -v2 --rules babelRules.xml --internalize --ildasm --noinvalid –msilencrypt .* --
makeproject .\myapp.blproj

Generates the myapp.blproj MSBuild project file:

<?xml version="1.0" encoding="utf-8"?>


<Project ToolsVersion="3.5" DefaultTargets="Obfuscate"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,
PublicKeyToken=138d17b5bd621ab7" />
<PropertyGroup>
<BabelInputFile>myapp.exe</BabelInputFile>
122

<OverloadedRenaming>true</OverloadedRenaming>
<StringEncryption>true</StringEncryption>
<FlattenNamespaces>true</FlattenNamespaces>
<DeadCodeElimination>false</DeadCodeElimination>
<ILIterations>3</ILIterations>
<DynamicProxy>None</DynamicProxy>
<BabelOutputFile>myapp.exe</BabelOutputFile>
<SealClasses>false</SealClasses>
<ShowLogo>true</ShowLogo>
<MsilEncryption>.*</MsilEncryption>
<ShowStatistics>true</ShowStatistics>
<ObfuscateXaml>false</ObfuscateXaml>
<VerboseLevel>2</VerboseLevel>
<ObfuscateProperties>true</ObfuscateProperties>
<SuppressIldasm>false</SuppressIldasm>
<ObfuscateFields>true</ObfuscateFields>
<GenerateDebug>false</GenerateDebug>
<ObfuscateMethods>true</ObfuscateMethods>
<EnableObfuscationAgent>true</EnableObfuscationAgent>
<SuppressReflection>false</SuppressReflection>
<ControlFlowObfuscation>
true;token=false;underflow=false;goto=true;if=true;switch=true;case=true
</ControlFlowObfuscation>
<VirtualFunctions>true</VirtualFunctions>
<ObfuscateEvents>true</ObfuscateEvents>
<ObfuscateTypes>true</ObfuscateTypes>
<ResourceEncryption>false</ResourceEncryption>
<UnicodeNormalization>true</UnicodeNormalization>
</PropertyGroup>
<ItemGroup>
<MergeAssembly Include="myapp.Core.dll" />
<MergeAssembly Include="myapp.Data.dll" />
<MergeAssembly Include="myapp.Effects.dll" />
<MergeAssembly Include="myapp.Resources.dll" />
</ItemGroup>
<ItemGroup>
<RuleFile Include="babelRules.xml" />
</ItemGroup>
<Target Name="Obfuscate">
<Message Text="Obfuscating $(BabelInputFile)..." />
<Babel InputFile="$(BabelInputFile)" OutputFile="$(BabelOutputFile)" MergeAssemblies="@(MergeAssembly)"
RulesFiles="@(RuleFile)" ShowLogo="$(ShowLogo)" EnableObfuscationAgent="$(EnableObfuscationAgent)"
FlattenNamespaces="$(FlattenNamespaces)" UnicodeNormalization="$(UnicodeNormalization)"
ObfuscateTypes="$(ObfuscateTypes)" ObfuscateEvents="$(ObfuscateEvents)" ObfuscateMethods="$(ObfuscateMethods)"
ObfuscateProperties="$(ObfuscateProperties)" ObfuscateFields="$(ObfuscateFields)"
ObfuscateXaml="$(ObfuscateXaml)" VirtualFunctions="$(VirtualFunctions)"
OverloadedRenaming="$(OverloadedRenaming)" ControlFlowObfuscation="$(ControlFlowObfuscation)"
ILIterations="$(ILIterations)" StringEncryption="$(StringEncryption)" MsilEncryption="$(MsilEncryption)"
DynamicProxy="$(DynamicProxy)" ResourceEncryption="$(ResourceEncryption)" SuppressIldasm="$(SuppressIldasm)"
SuppressReflection="$(SuppressReflection)" SealClasses="$(SealClasses)"
DeadCodeElimination="$(DeadCodeElimination)" GenerateDebug="$(GenerateDebug)" VerboseLevel="$(VerboseLevel)"
ShowStatistics="$(ShowStatistics)" />
</Target>
</Project>

Once we have the project file, it is possible to perform the same obfuscation with msbuild.exe or babel.exe:

msbuild.exe myapp.blproj

babel.exe --project myapp.blproj

MSBuild will start Babel passing the same command line switches used earlier.
123

Task Attributes

There are many attributes available to customize the obfuscation process under MSBuild. The following table
shows all the known Babel task attributes and the related properties defined in the Babel.Build.targets file.

Task Attribute Babel.Build.targets Type Description

Miscellaneous

Directory to babel.exe
BabelDirectory BabelDirectory String tool (Obsolete use
ToolPath)
Directory to babel.exe
ToolPath ToolPath String
tool
ToolExe ToolExe String babel.exe
Global switch to
EnableObfuscation
- Boolean enable or disable the
obfuscation process
Outputs Babel
ShowLogo ShowLogo Boolean
copyright information
Whether you want
ShowStatistics ShowStatistics Boolean Babel to show
obfuscation statistics
Console output
VerboseLevel VerboseLevel Int32
verbosity
XAP package
XapCompressionLevel XapCompressionLevel Int32
compression level
Whether to enable
EnableObfuscationAgent EnableObfuscationAgent Boolean
agent task processing
Whether to detect if
DetectIfObfuscated DetectIfObfuscated String the target assembly is
already obfuscated
- BabelRulesFileName String BabelRules.xml
List of assembly files
SatelliteAssemlies SatelliteAssemlies String to process as satellite
assemblies
List of directories
where Babel searches
SearchDirectories SearchDirectories String
to resolve referenced
assemblies
List of regular
expressions to match
against deployed XAP
package assemblies
TakeFiles
BabelTakeFiles String that should be
obfuscated. This
property is equivalent
to the –take Babel
command line switch.
124

List of regular
expressions to match
against deployed XAP
package assemblies
SkipFiles BabelSkipFiles String that should not be
obfuscated. This
property is equivalent
to the –skip Babel
command line switch.
List of warning
NoWarnings NoWarnings String message codes to
ignore
Any messages that
would ordinarily be
reported as warnings
WarningsAsErrors WarningsAsErrors String are instead reported
as errors, and the
obfuscation process is
halted.
Set the path to the
DbgHelpDllDir DbgHelpDllDir String
dbghelp.dll

Set usage options as


Use Use Key=Value
key value pair

List of quick rule


QuickRules QuickRules String
definitions

Set full path to the


License License String license file or license
file search directories

Merge and Embed Assemblies


List of assembly files
MergeAssemblies MergeAssemblies String to merge into the
primary assembly
Whether merged
types have their
Internalize MergeInternalize Boolean
visibility restricted to
the assembly
Whether assembly-
level attributes of
CopyAttributes MergeCopyAttributes Boolean/String merged assemblies
are copied into the
target assembly.

List of assembly files


EmbedAssemblies EmbedAssemblies String to embed into the
primary assembly
125

Renaming

Whether to obfuscate
ObfuscateTypes ObfuscateTypes Boolean
the names of types
Whether to obfuscate
ObfuscateEvents ObfuscateEvents Boolean
the names of events
Whether to obfuscate
ObfuscateMethods ObfuscateMethods Boolean
the names of methods
Whether to obfuscate
ObfuscateParameters ObfuscateParameters Boolean the names of
parameters
Whether to obfuscate
ObfuscateProperties ObfuscateProperties Boolean the names of
properties
Whether to obfuscate
ObfuscateFields ObfuscateFields Boolean
the names of fields
(Boolean) Whether to
Boolean/ obfuscate the symbols
ObfuscateXaml ObfuscateXaml
Key=Value inside XAML/BAML
resources.
Whether to enable
VirtualFunctions VirtualFunctions Boolean virtual member name
obfuscation
Whether to overload
Boolean/
OverloadedRenaming OverloadedRenaming method names when
Key=Value
possible
Set the minimum
name string length to
NameLength NameLength Int32 use when generating
obfuscated symbols
names
Set obfuscated
NamePrefix NamePrefix String
symbol name prefix
Whether namespace
names information
FlattenNamespaces should have their
FlattenNamespaces Boolean
types’ visibility
restricted to the
assembly
Set the pat to XML
XmlDoc XmlDoc Boolean/String
documentation file

Whether to obfuscate
UnicodeNormalization UnicodeNormalization Boolean/String member names using
Unicode symbols

Control Flow Obfuscation


Whether to enable
Boolean
ControlFlowObfuscation ControlFlowObfuscation MSIL control flow
Key=Value
obfuscation
Number of iterations
ControlFlowIterations ILIterations used in the control
ILIterations Int32
Itertions flow obfuscation
algorithm.
126

Whether to emit
EmitInvalidOpcodes EmitInvalidOpcodes Boolean
invalid op-codes

Encryption and Protection


Whether to enable
code encryption for
methods that are
addressed by the msil
encryption feature.
MsilEncryption
MsilEncryption Boolean/String Optionally a given
regular expression
can be specified to
encrypt the methods
that match their
signature
Whether to enable
encryption of user
strings. Optionally the
StringEncryption StringEncryption Boolean/String
encryption string
algorithm name can
be specified.
Whether to encrypt
Boolean/
ValueEncryption ValueEncryption Inline Values and
Key=Value
Arrays
Whether to encrypt
ResourceEncryption ResourceEncryption Boolean
Resources

Whether to wrap calls


Boolean/ to external assemblies
DynamicProxy DynamicProxy
Key=Value in proxies generated
dynamically

Whether to prevent
ILDASM from
SuppressIldasm SuppressIldasm Boolean
disassembling the
obfuscated target
Whether to prevent
tools using reflection
SuppressReflection SuppressReflection Boolean
from displaying
metadata.

Whether to enable the


generation of
TamperingDetection TamperingDetection Boolean
tampering detection
code

Whether to enable
DebuggingProtection DebuggingProtection Boolean anti debugging
protection
127

Code Generation

List of assembly files


AddReference AddReference String to reference into the
primary assembly
Whether to enable
inline expansion for
InlineExpansion InlineExpansion Boolean methods that are
addressed by the
inline feature
(Boolean) Whether to
enable code
instrumentation.
(String) A list of
Instrument BabelInstrument Boolean/String
regular expressions to
match methods full
name that will be
instrumented.

Whether to enable the


InstrumentEmptyMethods InstrumentEmptyMethods Boolean instrumentation of
empty methods
Whether to remove
DeadCodeElimination DeadCodeElimination Boolean unused methods from
the target assembly

Whether to seal
SealClasses SealClasses Boolean classes whenever
possible
(Boolean) Whether to
cleanup unwanted
attributes. (String) A
list of regular
CleanAttributes CleanAttributes Boolean/String expressions can be
specified to filter
unwanted attributes
according their full
type name.
Whether to enable
EnumRemoval EnumRemoval Boolean System.Enum types
removal
Whether to enable
ConstRemoval ConstRemoval Boolean constant fields
removal

Whether to enable
DisgregateRemoval DisgregateRemoval Boolean properties and event
metadata removal

GenerateDebug GenerateDebug Boolean Whether to enable


debug symbols
generation
128

Output Files

Obfuscated target file


OutputFile BabelOutputFile String
path

Debug symbols file


PdbFile PdbFile String
path

PdbPwd PdbPwd String Set PDB file password

Whether to generate
obfuscation log. The
GenerateLogFile GenerateLogFile Boolean
file name will be:
<assembly>.log

Obfuscation log file


LogFile BabelLogFile String
path

Whether to generate
obfuscation map file.
GenerateMapOutFile GenerateMapOutFile Boolean The map file name will
be:
<assembly>.xml.map

MapOutFile BabelMapOutFile String Output map file path

Input Files

The path of the main


InputFile BabelInputFile String source assembly
(mandatory)
Path of the strong-
KeyFile KeyOriginatorFile String
name key file
KeyContainer KeyContainerName String Key container name

Strong-name
KeyPwd SigningCertPassword String
certificate password

Android key store file


AndroidSigningKeyStore AndroidSigningKeyStore String
(APK Package)

Android key store


AndroidSigningKeyPass AndroidSigningKeyPass String password (APK
Package)
Android key store
AndroidSigningKeyAlias AndroidSigningKeyAlias String
alias (APK Package)

Android store
AndroidSigningStorePass AndroidSigningStorePass String password (APK
Package)
BabelRulesFiles Semicolon-separated
RulesFiles String
list of rules file paths
129

ItemGroup element:
BabelRules

BabelMapInFiles
List of XML map files
MapInFiles String
ItemGroup element: to process
MapInFile

Table 6 Babel task attributes


130

Using Babel Task in Visual Studio

You can obfuscate the assemblies compiled in a Visual Studio project by adding the Babel task in the
AfterBuild Target as follows:

1) In Visual Studio Solution Explorer, select the project node, right-click, and from the context popup
menu choose the Unload Project command. When the project is unloaded, its icon changes to a
folder and the word '(unavailable)' appears next to it.

2) Right click the unloaded project, and from context popup menu choose Edit.
3) In the Visual Studio project file locates the last MSBuild Import element. There you will find the
BeforeBuild and AfterBuild targets commented.

4) Add the UsingTask Babel under the Import element and uncomment the AfterBuild target:

<Import
Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\$(VisualStudioVersion)\Microsoft.Wind
ows.UI.Xaml.CSharp.targets" />

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7" />

<!-- 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>

5) Insert the Babel task inside the AfterBuild element and add the obfuscation attributes

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7" />
<!-- 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">
131

</Target>
-->
<Target Name="AfterBuild">
<Babel InputFile="$(TargetPath)"
OutputFile="$(TargetPath)"
ObfuscateTypes="true"
ObfuscateEvents="true"
ObfuscateMethods="true"
ObfuscateProperties="true"
ObfuscateFields="true"
VirtualFunctions="true"
FlattenNamespaces="true"
StringEncryption="hash"
/>
</Target>
</Project>

6) Save the project file and from Visual Studio Solution Explorer, right-click the project node and choose
the Reload Project command.

You can now rebuild the solution and see in the Visual Studio Output window the Babel Obfuscator
command output:

Using Babel Task in Xamarin Studio

Xamarin Studio is a modern development environment for creating applications targeting Android and iOS
devices. Because Xamarin Studio build are based on MSBuild, if you have installed Xamarin Studio on
132

Window you can obfuscate your assembly directly in Xamarin Studio by adding the Babel task in the project
file.

1) Open your solution in Xamarin Studio and from the Solution panel right click the project node and
select Unload

2) Right click the unloaded project and choose Tools then Edit File

3) Append the required UsingTask element to reference the assembly containing the MSBuil Babel task.
4) Add the Babel task inside the AfterBuild Target.

<Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.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. -->
<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,
PublicKeyToken=138d17b5bd621ab7" />
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
<ItemGroup>
<RuleFile Include="babelRules.xml" />
</ItemGroup>
<Babel InputFile="$(TargetPath)" OutputFile="$(TargetPath)" VerboseLevel="5"
ObfuscateTypes="true"
ObfuscateEvents="true"
ObfuscateMethods="true"
ObfuscateProperties="true"
ObfuscateFields="true"
VirtualFunctions="true"
UnicodeNormalization="false"
FlattenNamespaces="false"
StringEncryption="hash"
ResourceEncryption="true"
ValueEncryption="true"
DynamicProxy="all"
SuppressIldasm="true"
133

ControlFlowObfuscation="goto=on;if=on;switch=on;case=on;call=on"
ILIterations="5" />
</Target>
<ItemGroup>
<Folder Include="Resources\drawable-hdpi\" />
<Folder Include="Resources\drawable-ldpi\" />
<Folder Include="Resources\drawable-mdpi\" />
<Folder Include="Resources\drawable-xhdpi\" />
<Folder Include="Resources\drawable-xxhdpi\" />
</ItemGroup>
<ItemGroup>

5) Save the changes made to the project file.

After reloading the project you can switch to Release build and rebuild your solution. Xamarin Studio will
create the .apk package file using the obfuscated assembly created during the build process.

Note that UnicodeNormalization and FlattenNamespaces options must be disabled otherwise Xamarin
build will raise an errors when compiling the auto-generated Java stub types.

If you want to enable namespace flattening, you can set:

FlattenNamespaces="a"

This will set the default namespace to ‘a’ for all obfuscated types.
134

Visual Studio Build


This section will describe how you can use Babel Obfuscator with common build tools like Visual Studio and
MSBuild. Visual Studio integration offers two different ways of obfuscating project assemblies:
The first consists in launching babel.exe from the post-build event Project Designer page. The second
involves the editing of Visual Studio project files and it invokes Babel’s MSBuild task.
135

Post Build Event

The simplest way to start Babel Obfuscator from within Visual Studio is using a post build event. Just open the
Build Events page of the Project Designer to specify the babel.exe post build command:

babel.exe "$(TargetDir)$(TargetFileName)" -v1 --keyfile "$(ProjectDir)StrongName.snk" --rules


"$(ProjectDir)babelRules.xml"
To successfully run the event command, babel.exe must be available in your system PATH. The command-
line syntax can include any build macro.

Visual Studio Project File

Beside build events, Babel Obfuscation can be added to a Visual Studio project file using the Babel MSBuild
task. This is not as easy as adding a post-build event but ensures a better tuning.

There are two ways you can integrate the Babel task in a Visual Studio project:

1) By adding the Babel task directly into the project file defining a new build target
2) By importing the Babel.Build.targets that plug-in an Obfuscation target inside your build pipeline

The first method has been described in the previous paragraph (How to Add the Babel Task in Visual Studio).

To import the Babel.Build.targets into your project file:

1) In Visual Studio Solution Explorer, select the project node, right-click, and from the context popup
menu choose the Unload Project command.
2) Right click the unloaded project, and from context popup menu choose Edit.
3) In the XML project file insert after the line:

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

The following Import declaration:

<Import Project="<full path to Babel.Build.targets file>" />

For example:

<Import Project="C:\Program Files\Babel\MSBuild\Babel.Build.targets" />

4) Save and reload the project.

Rebuild the project and look at the Visual Studio Output panel to see Babel console output. The obfuscated
assembly is saved to BabelOut sub-folder relative to the target directory.

The Babel.Build.targets file imports the Babel MSBuild task and defines some common task properties. These
properties can be overridden in your (.*proj) file to customize the Babel task behavior.
For instance, in Babel.Build.targets the property UnicodeNormalization is set to true to enable Unicode
normalization:

<PropertyGroup>
<UnicodeNormalization>true</UnicodeNormalization>
</PropertyGroup>

If you want to disable Unicode normalization, you can override this property in your project file by adding after
the Import declaration the following lines:
136

<PropertyGroup>
<UnicodeNormalization>false</UnicodeNormalization>
</PropertyGroup>

Other properties are available to override.


The full set of properties defined into Babel.Build.targets file is available in Table 7 Babel task attributes.

Add an XML Rule File in Visual Studio Project

When Babel is imported through the Babel.Build.targets file in a Visual Studio Project (see
Visual Studio Integration), the simplest way to add an XML Rules file is to add to the Visual Studio Project an
XML file named BabelRules.xml. To Add an XML rules file do the following steps:

1) In Visual Studio Solution Explorer, right-click on the project node and select from the popup menu
Add -> New Item…
2) From the Add New Item dialog, select an XML file template and enter into the Name text field:

BabelRules.xml.

3) Fill the XML file with rule definitions.


4) Save and build the project.

Enable Obfuscation on Release Build

You can enable or disable Babel obfuscation according to a build configuration. If you want to enable
Obfuscation only in Release build you can add the following snippet of XML code in your Visual Studio project
file:

<Import Project="C:\Program Files\Babel\MSBuild\Babel.Build.targets" />


<Choose>
<When Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup>
<EnableObfuscation>false</EnableObfuscation>
</PropertyGroup>
</When>
<When Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PropertyGroup>
<EnableObfuscation>true</EnableObfuscation>
<ILIterations>3</ILIterations>
<StringEncryption>true</StringEncryption>
</PropertyGroup>
</When>
</Choose>

When the Debug build is selected, the Babel task is disabled and babel.exe is not executed at the end of the
build process. Switching the build configuration to Release will enable the Obfuscation. If you are referencing
the Babel task directly inside your project, just add the Condition to the enclosed MSBuild Task element.

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7" />
<Target Name="AfterBuild" Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Babel InputFile="$(TargetPath)" />
</Target>
137

Setup Obfuscation for Silverlight

To obfuscate a Silverlight XAP package directly, override the AfterBuild target and create the BabelInputFile
property inside MSBuild as follow:

<Import Project="C:\Program Files\Babel\MSBuild\Babel.Build.targets" />

<Target Name="AfterBuild">
<CreateProperty Value="@(_OutputPathItem->'%(FullPath)$(XapFilename)')">
<Output TaskParameter="Value" PropertyName="BabelInputFile"/>
</CreateProperty>
</Target>

The AfterBuild target will create the BabelInputFile property with the correct path to the XAP package.

Setup Obfuscation for ClickOnce

In ClickOnce deploy Visual Studio sign the deployed package.

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

<!-- Add Babel task using -->


<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,
PublicKeyToken=138d17b5bd621ab7" />

<Target Name="Obfuscate" AfterTargets="Compile">

<!-- Setup obfuscation -->


<Babel InputFile="$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)"
OutputFile="$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)" ObfuscateTypes="true"
ObfuscateEvents="true" ObfuscateMethods="true" ObfuscateProperties="true"
ObfuscateFields="true" VirtualFunctions="true" UnicodeNormalization="true"
FlattenNamespaces="true" OverloadedRenaming="true" StringEncryption="hash"
ControlFLowObfuscation="goto=on;if=on;switch=on;call=on" ControlFLowIterations="3"
SuppressIldasm="true" />
</Target>

The Obfuscate target will run just after Compile target to obfuscate the deployed assembly.

Note that the BeforeTargets and AfterTargets are available starting with MSBuild 4.0. If you are using an early
version of MSBuild, you can change the build order by overriding the one provided for ClickOnce applications.

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7" />
<PropertyGroup>
<CoreBuildDependsOn>
BuildOnlySettings;
PrepareForBuild;
PreBuildEvent;
ResolveReferences;
PrepareResources;
ResolveKeySource;
Compile;
Obfuscate;
ExportWindowsMDFile;
UnmanagedUnregistration;
GenerateSerializationAssemblies;
CreateSatelliteAssemblies;
138

GenerateManifests;
GetTargetPath;
PrepareForRun;
UnmanagedRegistration;
IncrementalClean;
PostBuildEvent
</CoreBuildDependsOn>
</PropertyGroup>
<Target Name="Obfuscate">
<!-- Setup obfuscation -->
<Babel InputFile="$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)"
OutputFile="$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)" ObfuscateTypes="true"
ObfuscateEvents="true" ObfuscateMethods="true" ObfuscateProperties="true"
ObfuscateFields="true" VirtualFunctions="true" UnicodeNormalization="true"
FlattenNamespaces="true" OverloadedRenaming="true" StringEncryption="hash"
ControlFLowObfuscation="goto=on;if=on;switch=on;call=on" ControlFLowIterations="3"
SuppressIldasm="true" />
</Target>

Setup Obfuscation for Windows Store

To obfuscate an application targeting the Windows Store edit the Visual Studio project file and append under
the XML comment:

<!-- 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.
-->

The following MSBuild directives:

<Import Project="C:\Program Files\Babel\MSBuild\Babel.Build.targets" />


<PropertyGroup>
<BabelOutputFile>$(TargetPath)</BabelOutputFile>
</PropertyGroup>

Alternatively you can add the UsingTask element and access directly all the Babel task properties you want to
configure:

<!-- 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.
-->
<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,
PublicKeyToken=138d17b5bd621ab7" />
<Target Name="AfterBuild">
<Babel InputFile="$(TargetPath)"
OutputFile="$(TargetPath)"
ObfuscateTypes="true"
ObfuscateEvents="true"
ObfuscateMethods="true"
ObfuscateProperties="true"
ObfuscateFields="true"
VirtualFunctions="true"
FlattenNamespaces="true"
StringEncryption="hash"
/>
</Target>
139

This will configure Babel Obfuscator to obfuscate the build output in place, making easy the next deployment
step with Visual Studio.

Setup Obfuscation for .NET Micro Framework and


nanoFramework

Assemblies compiled for .NET Nano and Micro frameworks need to be further processed by .NET compilers
before being deployed to the target. This additional compilation step is performed to ensure the binary
compatibility with the target device. The obfuscation process must be carried out before this final step. This
can be achieved by importing into your project file the Babel.Build.targets MSBuild file as follows:

.NET Micro Framework


<Import Project="$(NetMfTargetsBaseDir)$(TargetFrameworkVersion)\CSharp.Targets" />
<Import Project="C:\Program Files\Babel\MSBuild\Babel.Build.targets" />

nanoFramework
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets"
Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
<Import Project="C:\Program Files\Babel\MSBuild\Babel.Build.targets" />

To enable enhanced obfuscation features, configure the Babel MSBuild task adding the following section:

<Import Project="$(NetMfTargetsBaseDir)$(TargetFrameworkVersion)\CSharp.Targets" />


<Import Project="C:\Program Files\Babel\MSBuild\Babel.Build.targets" />
<Choose>
<When Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup>
<EnableObfuscation>true</EnableObfuscation>
<SuppressReflection>true</SuppressReflection>
</PropertyGroup>
</When>
<When Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PropertyGroup>
<EnableObfuscation>true</EnableObfuscation>
<SuppressReflection>true</SuppressReflection>
</PropertyGroup>
</When>
</Choose>

Please refer to the Technology Matrix to see which obfuscation features are available in the .NET Micro
Framework and nanoFramework.
140

Setup Obfuscation for Windows Phone

This sample will show how to setup obfuscation in a Visual Studio 2010 project for a Windows Phone 7.x
Silverlight project using XAML code renaming.

To obfuscate a Silverlight XAP package build for Windows Phone 7 from within Visual Studio 2010, just edit
the Visual Studio project file by inserting the necessary Babel task XML instructions to configure the
obfuscation process:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for


Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />
<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,
PublicKeyToken=138d17b5bd621ab7" />
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
<Babel InputFile="$(OutputPath)$(ProjectName).xap"
OutputFile="$(OutputPath)$(ProjectName).xap"
GenerateDebug="true"
FlattenNamespaces="true"
StringEncryption="true"
ControlFlowObfuscation="true"
ObfuscateXaml="true">
</Babel>
</Target>
<ProjectExtensions />
</Project>

The first XML element to insert is the UsingTask instruction that maps the Babel task element to the assembly
Babel.Build installed into the GAC. The Babel task element was inserted as a child of the AfterBuild Target
element to ensure that the obfuscation is performed right after the build process terminates.

Then set the InputFile and the OutputFile properties to the path of the XAP file produced during the build:
$(OutputPath)$(ProjectName).xap. Babel will obfuscate in place the XAP package, facilitating the deployment
to the device.
141

Setup Obfuscation for Xamarin Forms

When obfuscating Xamarin Forms applications using Visual Studio, Babel Obfuscator needs to run before
Visual Studio collects the assemblies to make the deployment package. To do so, Babel task needs to be
injected in the build pipeline properly to obtain the obfuscated package. The build configuration depends on
which build environment is used.

Babel Obfuscation of Xamarin.Forms solution for Android and iOS


To build a Xamarin Form application in Visual Studio Professional or Enterprise under MAC OSX follow the
steps:

1. Configure iOS signing identity and provisioning profile


2. Add Babel task to your vsproj file for Droid and iOS projects

<Import Project="..\packages\Xamarin.Forms.3.4.0.1008975\build\Xamarin.Forms.targets"
Condition="Exists('..\packages\Xamarin.Forms.3.4.0.1008975\build\Xamarin.Forms.targets')" />
<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,
PublicKeyToken=138d17b5bd621ab7" />
<PropertyGroup>
<NameLength>3</NameLength>
<ObfuscateEvents>true</ObfuscateEvents>
<ObfuscateFields>true</ObfuscateFields>
<ObfuscateMethods>true</ObfuscateMethods>
<ObfuscateParameters>true</ObfuscateParameters>
<ObfuscateProperties>true</ObfuscateProperties>
<ObfuscateTypes>true</ObfuscateTypes>
<StringEncryption>hash</StringEncryption>
<ControlFlowObfuscation>goto=on;if=on;switch=on;call=on</ControlFlowObfuscation>
<ShowStatistics>true</ShowStatistics>
<SuppressIldasm>false</SuppressIldasm>
<UnicodeNormalization>false</UnicodeNormalization>
<OverloadedRenaming>false</OverloadedRenaming>
<FlattenNamespaces>false</FlattenNamespaces>
<VerboseLevel>5</VerboseLevel>
<VirtualFunctions>false</VirtualFunctions>
<GenerateDebug>true</GenerateDebug>

<Obfuscate1Dir>$(SolutionDir)/AppAndroid/AppAndroid/bin/$(ConfigurationName)/netstandard2.0</Obfus
cate1Dir>
<Obfuscate2Dir>$(TargetDir)</Obfuscate2Dir>
</PropertyGroup>
<ItemGroup>
<SearchDirectory Remove="@(SearchDirectory)" />
<SearchDirectory Include="$(Obfuscate1Dir)" />
<SearchDirectory Include="$(Obfuscate2Dir)" />
<SearchDirectory Include="$(ProjectDir)/$(IntermediateOutputPath)/android/assets" />
</ItemGroup>
<Target Name="Obfuscate1" Condition=" '$(Configuration)' == 'Release' "
BeforeTargets="_ConvertPdbFiles">
<Babel SearchDirectories="@(SearchDirectory)"
InputFile="$(Obfuscate1Dir)/AppAndroid.dll" OutputFile="$(Obfuscate1Dir)/AppAndroid.dll"
GenerateDebug="$(GenerateDebug)" ObfuscateEvents="$(ObfuscateEvents)"
ObfuscateFields="$(ObfuscateFields)" ObfuscateMethods="$(ObfuscateMethods)"
ObfuscateParameters="$(ObfuscateParameters)" ObfuscateProperties="$(ObfuscateProperties)"
ObfuscateTypes="$(ObfuscateTypes)" OverloadedRenaming="$(OverloadedRenaming)"
VirtualFunctions="$(VirtualFunctions)" FlattenNamespaces="$(FlattenNamespaces)"
ShowStatistics="$(ShowStatistics)" StringEncryption="$(StringEncryption)"
ControlFlowObfuscation="$(ControlFlowObfuscation)" SuppressIldasm="$(SuppressIldasm)"
UnicodeNormalization="$(UnicodeNormalization)" VerboseLevel="$(VerboseLevel)" />
</Target>
142

<Target Name="Obfuscate2" Condition=" '$(Configuration)' == 'Release' "


AfterTargets="Obfuscate1">
<Babel SearchDirectories="@(SearchDirectory)"
InputFile="$(Obfuscate2Dir)/AppAndroid.Android.dll"
OutputFile="$(Obfuscate2Dir)/AppAndroid.Android.dll" GenerateDebug="$(GenerateDebug)"
ObfuscateEvents="$(ObfuscateEvents)" ObfuscateFields="$(ObfuscateFields)"
ObfuscateMethods="$(ObfuscateMethods)" ObfuscateParameters="$(ObfuscateParameters)"
ObfuscateProperties="$(ObfuscateProperties)" ObfuscateTypes="$(ObfuscateTypes)"
OverloadedRenaming="$(OverloadedRenaming)" VirtualFunctions="$(VirtualFunctions)"
FlattenNamespaces="$(FlattenNamespaces)" ShowStatistics="$(ShowStatistics)"
StringEncryption="$(StringEncryption)" ControlFlowObfuscation="$(ControlFlowObfuscation)"
SuppressIldasm="$(SuppressIldasm)" UnicodeNormalization="$(UnicodeNormalization)"
VerboseLevel="$(VerboseLevel)" />
</Target>
</Project>

Note that there are two Babel tasks, one set for the Android assembly and one for the Portable library.

3. Set <ObfuscateDirectory>. This directory should point the intermediate build output directory in the
cross-platform project. If unsure of the relative path, set to the full absolute path.
4. Set <SearchDirectory> to include correct Microsoft.NETCore.App directory in both the Android and
iOS csproj files
5. Rebuild solution
6. Release builds for Android and iOS will be obfuscated

The full example project is available to download at babelfor.NET:

http://www.babelfor.net/media/downloads/AppAndroid.zip

Merging Babel Licensing


If you are using Babel Licensing to license your Android application, you might like to merge Babel Licensing
with the *.Android.dll DLL in order to get a better obfuscation of the licensing code.
To merge Babel Licensing component, add to the Babel task for the Obfuscate2 target the instructions to
merge Babel.Licensing.Android.dll:

MergeAssemblies="$(ObfuscateDirectory)/Babel.Licensing.Android.dll" Internalize="true"

The internalize property set to true will make all the public types inside Babel.Licensing.Android.dll internal, so
that they will be renamed during the obfuscation.

As the Babel.Licensing.Android.dll component is now merged, you don’t need to deploy it anymore inside the
APK package.

To create the APK that doesn’t contain the merged Babel Licensing assembly, add a Task that run before the
target _PrepareAssemblies and deletes the merged assembly from the directory
$(MonoAndroidIntermediateAssetsDir) used as source to prepare the APK Package:

<Target Name="DeleteMergedAssemblies" Condition=" '$(Configuration)' == 'Release' "


BeforeTargets="_PrepareAssemblies">
<Delete Files="$(MonoAndroidIntermediateAssetsDir)Babel.Licensing.Android.dll" />
</Target>

Babel Obfuscation in Visual Studio 2017 for Mac

1. To the extent possible, set the scope of classes and members to private or internal so that Babel
obfuscates their names.
2. Add the Babel build tasks to the Android and iOS csproj files as in the example
143

a. For iOS, it is important to control the build task order with

AfterTargets="PrepareForBuild" BeforeTargets="_CoreCompileInterfaceDefinitions"

b. For Android, it is important to control the build task order of the two Babel build tasks by
creating build dependencies as shown in the example and by making sure that the Babel
build tasks happen

AfterTargets="_CopyIntermediateAssemblies" BeforeTargets="_ConvertPdbFiles"

The full example project is available to download at babelfor.NET

http://www.babelfor.net/media/downloads/PCLBabelExample.zip
144

Customizing Intellisense

The MSBuild Babel task attributes are defined into the schema file Babel.Build.xsd located inside the
\Program Files\Babel\MSBuild installation folded. To integrate Babel task with Visual Studio Intellisense,
copy the file Babel.Build.xsd into one of the following Visual Studio install folder:

VS 2012 to VS 2015
(x86) C:\Program Files\Microsoft Visual Studio 1x.0\Xml\Schemas\1033
(x64) C:\Program Files (x86)\Microsoft Visual Studio 1x.0\Xml\Schemas\1033

VS 2017
(x86) C:\Program Files\Microsoft Visual Studio\2017\<<edition>>\Xml\Schemas\1033
(x64) C:\Program Files (x86)\Microsoft Visual Studio\2017\<<edition>>\Xml\Schemas\1033

Where <<edition>> is one of the available Visual Studio edition: Professional, Enterprise.

Please refer to VS installation guide to know more.

and import it into the Microsoft.Build.xsd file as follow:

<!-- =================== IMPORT COMMON SCHEMA =========================== -->


<xs:include schemaLocation="MSBuild\Microsoft.Build.CommonTypes.xsd"/>
<xs:include schemaLocation="Babel.Build.xsd"/>

This will enable Intellisense or the Babel task inside the Visual Studio XML code editor.
145

Babel NuGet Package


The Babel.Obfuscator NuGet package distributed with the Company license setup, contains Babel Obfuscator
and Licensing tools for .NET Framework 4.6 and .NET Core 3.0. This makes Babel obfuscator and licensing
tools compatible with any build running dotnet.exe. This includes all development environments supporting
.NET Core and NuGet like the Linux Ubuntu and MAC OSX virtual machines hosted by DevOps.
This paragraph will show how to setup the obfuscation in Visual Studio and DevOps using the Babel
Obfuscator NuGet package.
146

Running Babel Obfuscator in Visual Studio

To obfuscate the assembly generated by Visual Studio during the build, add a reference to the Babel
Obfuscator NuGet package to your Visual Studio project.

The Babel.Obfuscator.nupkg file is available as separate download to all subscribers of a Babel Obfuscator
Company license. To install the NuGet package in your local machine, open Visual Studio and from the Tools
menu select Options. In the Options panel search for NuGet and select under the NuGet Package Manager
tree item the Package Sources node.

Press the button with the plus icon and ender in the Name field Babel and in the Source field the full path to
the folder containing the Babel.Obfuscator.nupkg file. Press the OK button.
147

To reference the Babel.Obfuscator NuGet package. In the Solution Explorer right chick your project file. Select
Manage NuGet Packages…

In the Package source combo box select your newly added Babel package source, then Install the
Babel.Obfuscator package.

Copy your license file babel.licenses in the solution folder and rebuild the solution.
Scroll down the Output window to see the obfuscation log.
148

Customize the Obfuscation


Once the obfuscation is setup and running, you can customize the obfuscation by editing directly the Visual
Studio project.
Unload the project file. After unloading the project, you can edit the project file with Visual Studio.
Under the list of package references, add a new target called SetupObfuscate as follow:

<ItemGroup>
<PackageReference Include="Babel.Obfuscator" Version="9.3.1" />
</ItemGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">


<BabelEnabled>false</BabelEnabled>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<BabelEnabled>true</BabelEnabled>
</PropertyGroup>

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<PropertyGroup>
<OverloadedRenaming>true</OverloadedRenaming>
<ControlFlowObfuscation>goto=on;if=on;switch=on;call=on</ControlFlowObfuscation>
<ILIterations>5</ILIterations>
<MsilEncryption>.*</MsilEncryption>
<VerboseLevel>1</VerboseLevel>
</PropertyGroup>
</Target>

</Project>

Optionally you can configure the obfuscation to run only on Release build by setting a condition on the
BabelEnabled property (see gray XML fragment above).

Reload the project. ThenNew settings will be applied with the next solution rebuild.

Setting Up a Common License File


Babel Obfuscator needs to access the license file during the build. By default, all Babel tools look in the
solution folder for the license file. You can specify a common place for all the solutions using any Babel tool
by setting the property BabelLicense to the full path to babel.licenses file:

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<PropertyGroup>
<BabelLicense>$(ProgramW6432)\Babel\babel.licenses</BabelLicense>
<OverloadedRenaming>true</OverloadedRenaming>
<ControlFlowObfuscation>goto=on;if=on;switch=on;call=on</ControlFlowObfuscation>
<ILIterations>5</ILIterations>
<MsilEncryption>.*</MsilEncryption>
<VerboseLevel>1</VerboseLevel>
</PropertyGroup>
</Target>

Adding Obfuscation Rules Files


Obfuscation rules can be configured by adding to the project an XML file named babelRules.xml.
You can also add multiple rules files to your project by configuring an ItemGroup the references all the rules
files you want to process as follow:

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<ItemGroup>
<BabelRules Include="renamingRules.xml" />
149

<BabelRules Include="codeRules.xml" />


</ItemGroup>
<PropertyGroup>
<OverloadedRenaming>true</OverloadedRenaming>
<ControlFlowObfuscation>goto=on;if=on;switch=on;call=on</ControlFlowObfuscation>

The ItemGroup elements should be named BabelRules.

Merge and Embed Assemblies


Merging or embedding assemblies to the obfuscation target is achieved by defining additional ItemGroup
elements:

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<ItemGroup>
<MergeAssembly Include="$(TargetDir)\Acme.View.dll" />
<MergeAssembly Include="$(TargetDir)\Acme.ViewModel.dll" />
</ItemGroup>
<ItemGroup>
<EmbedAssembly Include="$(TargetDir)\Framework.Mvvm.dll" />
<EmbedAssembly Include="$(TargetDir)\Acme.Wpf.dll" />
</ItemGroup>
<PropertyGroup>
<MergeInternalize>true</MergeInternalize>

When merging types from an external assembly, it is possible to change the visibility of merged types from
public to internal. This will make the renaming during obfuscation more effective. To internalize the merged
types, set the MergeInternalize property to true.

Mapping Files
To obfuscate the public interface of referenced assemblies, you need to setup the XML map files for your
target assembly. This can be done by adding an ItemGrop with many MapInFile child elements, one for each
mapping file to be processed:

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<ItemGroup>
<MapInFile Include="$(TargetDir)\Acme.View.dll.map.xml" />
<MapInFile Include="$(TargetDir)\Acme.ViewModel.dll.map.xml" />
</ItemGroup>
<PropertyGroup>
<GenerateMapOutFile>true</GenerateMapOutFile>

To generate the XML map file for a referenced assembly, set the property GenerateMapOutFile to true in the
obfuscation project of the referenced assembly. For more details about public obfuscation please refer to the
Cross Assembly Obfuscation paragraph.

Optimizations
Optimizations are disabled by default. If you want to enable optimizations you can set one or more of the
following to true:

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<PropertyGroup>

<!-- Optimizations -->


<DeadCodeElimination>false</DeadCodeElimination>
<SealClasses>false</SealClasses>
<EnumRemoval>false</EnumRemoval>
<ConstRemoval>false</ConstRemoval>
150

<DisgregateRemoval>false</DisgregateRemoval>
<InlineExpansion>false</InlineExpansion>
<CleanAttributes>false</CleanAttributes>
</PropertyGroup>
</Target>

Babel Plugins
If you want to use Babel plugins inside your project, you can reference a plugin by adding an ItemGroup with
BabelPlugin child elements as follow:

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<ItemGroup>
<BabelPlugin Include="Plugins\BabelEncryptPlugin.dll" />
</ItemGroup>
<PropertyGroup>
<PluginArguments>dictionary=exclusionlist.txt</PluginArguments>

Where Plugins refers to the directory inside your project folder containing all the plugins components.
Plugin arguments can be defined within the PluginsArguments element.

DevOps Integration

DevOps is the new build automation cloud-based platform provided by Microsoft. Babel Obfuscator and
Licensing tools can be plugged in your DevOps build environment by referencing in your Visual Studio project
the NuGet package Babel.Obfuscator.

To use Babel Obfuscator under DevOps, is required to run at least .NET Core 3.0 dotnet.exe build tools. This
can be setup before the build occurs using the following instructions:

steps:
# Use dotnet 3.x
- task: UseDotNet@2
displayName: 'Use dotnet sdk 3.x'
inputs:
version: 3.x
includePreviewVersions: false

This will install latest stable release of .NET Core 3 CLI tools. If you want to a use preview version, please set
the includePreviewVersions to true.

To reference Babel.Obfuscator NuGet package in your Visual Studio project, you need to upload the
Babel.Obfuscator nupkg file on your DevOps Artifacts feed and make sure that DevOps has the instructions to
restore NuGet packages from your NuGet feed.

NOTE that the Babel.Obfuscator NuGet package must be hosted on your private feed and not exposed
to any public available NuGet package repository.

To restore the package from your Artifacts feed, use the following YAML:

# Restore NuGet packages.


- task: DotNetCoreCLI@2
displayName: 'restore packages'
inputs:
command: 'restore'
projects: '**/*.csproj'
verbosityRestore: 'diagnostic'
feedsToUse: 'select'
includeNuGetOrg: true
151

vstsFeed: <YOUR ARTIFACTS FEED NAME>

Once the package is referenced in your Visual Studio project, this will add the Babel task to the build pipeline
which automatically obfuscate the target assembly.

Babel task properties can be overridden inside your Visual Studio project file by defining a new Target. This
Target must run before the Obfuscate target, to override the properties that are already defined for the Babel
task:

<ItemGroup>
<PackageReference Include="Babel.Obfuscator" Version="9.3.1" />
</ItemGroup>
<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">
<PropertyGroup>
<OverloadedRenaming>true</OverloadedRenaming>
<ControlFlowObfuscation>goto=on;if=on;switch=on;call=on</ControlFlowObfuscation>
</PropertyGroup>
</Target>

Babel tools need a Company license file to run on DevOps. To install your Company license on DevOps just
add the license file babel.licenses to your solution folder. Babel tasks are configured to load the license file
from the solution root folder. If you want to change the location of your babel.licenses file, you can add the
BabelLicense property to set your license file path:

<Target Name="SetupObfuscate" BeforeTargets="Obfuscate">


<PropertyGroup>
<OverloadedRenaming>true</OverloadedRenaming>
<ControlFlowObfuscation>goto=on;if=on;switch=on;call=on</ControlFlowObfuscation>
<BabelLicense>$(ProjectDir)babel.licenses</BabelLicense>
</PropertyGroup>
</Target>

The list of overridable Babel task properties are available in Table 7 Babel task attributes.

Create License Files in DevOps

The MSBuild Lic task can be used to generate license files under DevOps. To create a license file for the
obfuscated assembly, add a new Target for the Lic task that runs after the Obfuscate target.

<Target Name="MakeLicense" AfterTargets="Obfuscate">


<PropertyGroup>
<BabelLicense>$(SolutionDir)babel.licenses</BabelLicense>
<Format>xml</Format>
<GenerateKeyInfo>false</GenerateKeyInfo>
<GenerateLogFile>false</GenerateLogFile>
<LicInputFile>$(TargetPath)</LicInputFile>
<LicOutputFile>$(TargetName).licenses</LicOutputFile>
<KeyFile>keypair.snk</KeyFile>
<Verify>true</Verify>
<ShowLogo>true</ShowLogo>
<VerboseLevel>4</VerboseLevel>
<Sign>rsa</Sign>
</PropertyGroup>
<ItemGroup>
<Product Include="Our App">
<Name>ACME</Name>
<Version>1.0.0.0</Version>
</Product>
</ItemGroup>
<ItemGroup>
<Licensee Include="Licensee">
152

<Company>Company</Company>
</Licensee>
</ItemGroup>
<ItemGroup>
<Restriction Include="domain">
<Name>localhost</Name>
</Restriction>
</ItemGroup>
<Message Text="Licensing $(LicInputFile)..." Importance="high" />
<Lic InputFile="$(LicInputFile)" OutputFile="$(LicOutputFile)" License="$(BabelLicense)"
KeyFile="$(KeyFile)" ShowLogo="$(ShowLogo)" Product="@(Product)" Licensee="@(Licensee)"
Restrictions="@(Restriction)" Format="$(Format)" Sign="$(Sign)" Verify="$(Verify)"
GenerateLogFile="$(GenerateLogFile)" GenerateKeyInfo="$(GenerateKeyInfo)"
VerboseLevel="$(VerboseLevel)" />
</Target>

The Lic task need to load your Company license file to create a license. In order to license the Lic tool, ensure
you have set the License taks property to the license file path. To know more about the Lic task please refer
to the Babel Licensing user’s guide.

Handling Packages
Application packages like XAP, APPX and APK are a deployment unit that contains the assemblies, resources
and usually a manifest that describes the package structure.

Babel Obfuscator can handle the assemblies contained in a XAP, APPX or APK package directly without
working with individual assemblies outside the given package. Babel accepts as a primary assembly source
the package file and performs the obfuscation of all the assemblies inside the package.
153

XAP Packages

In a XAP package, the deployed assemblies are those listed as <AssemblyPart> element in the AppManifest
XML file as showed in the following AppManifest.xaml file:

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
EntryPointAssembly="SilverlightRichEdit" EntryPointType="SilverlightRichEdit.App"
RuntimeVersion="4.0.50401.0">
<Deployment.Parts>
<AssemblyPart x:Name="SilverlightRichEdit" Source="SilverlightRichEdit.dll" />
<AssemblyPart x:Name="RichEdit" Source="RichEdit.dll" />
<AssemblyPart x:Name="System.Xml.Serialization" Source="System.Xml.Serialization.dll" />
<AssemblyPart x:Name="System.Xml.Linq" Source="System.Xml.Linq.dll" />
<AssemblyPart x:Name="System.ComponentModel.DataAnnotations"
Source="System.ComponentModel.DataAnnotations.dll" />
</Deployment.Parts>
</Deployment>

It is common practice to avoid obfuscating all Silverlight assemblies. To filter the assemblies that babel should
obfuscate you can use the take and skip command line options. These two options accept a regular
expression as an argument and those assembly names that will match the given expression will be taken or
skipped by the obfuscator.

babel.exe SilverlightRichEdit.xap –-take .*RichEdit –-skip System.*

XAP Package Compression


Because the size of the XAP package affects the overall download time required to deliver the application to
the client, you can tweak the XAP package size increasing the compression level using the compress option:

babel.exe SilverlightRichEdit.xap –-take .*RichEdit –-skip System.* --mapout


-–compress 9

Admitted values are 0 (for no compression at all), to 9 (best compression). The size of the resulting package
depends on the content of the XAP package.

XAP Skip List


Silverlight XAP packages may contain assemblies that belong to the Silverlight library itself. These assemblies
should not be obfuscated, and they must be specified at the command line after the skip option. This
operation may require the user to enter long command line sentences especially when there are many
Silvelight assemblies inside the XAP package. To avoid this repetitive task the user can add all the
assemblies that are often skipped in the obfuscation process inside the babel.exe.config configuration file
using the XapSkipList section as follow:

<setting name="XapSkipList" serializeAs="Xml">


<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>System.Windows.Controls</string>
<string>System.Windows.Data</string>
<string>System.Xml.Linq</string>
</ArrayOfString>
</value>
</setting>
154

APPX Packages

The obfuscation of an APPX package is very similar to that of a XAP file. You can obfuscate an APPX
package directly from the command line by entering the APPX file path as follow:

babel.exe MyWinStoreApp.appx

Babel Obfuscator will obfuscate all the assemblies inside the package and produce a new APPX package in
the BabelOut directory. You can use --take and --skip command line options to set the assemblies to
obfuscate.

Babel Obfuscator uses the MakeAppx.exe command-line tool distributed with the Windows 8 Development Kit
to create a new obfuscated APPX package.
If Babel cannot locate the MakeAppx.exe tool path it raises an error during the obfuscation process. In this
case the user can specify the full path to the MakeAppx.exe in the babel.exe.config file using the following
settings

<setting name="MakeAppxExePath" serializeAs="String">


<value>C:\Program Files (x86)\Windows Kits\8.0\bin\x86\MakeAppx.exe</value>
</setting>

Babel can be configured to pass additional parameters at the MakeAppx.exe command line by adding these
options to MakeAppxExeOptions setting:

<setting name="MakeAppxExeOptions" serializeAs="String">


<value>/h SHA512 /v</value>
</setting>

The above settings can also be changed from the Babel Obfuscator user interface.
Please refer to the MakeAppx.exe guide to know all the available switches.

APPX Package Signing


Babel Obfuscator does not sign the obfuscated APPX package, so the obfuscated APPX package produced
by babel.exe needs to be digitally signed before its distribution. To digitally sign the APPX package, you need
to run the SignTool.exe command-line tool distributed with the Windows SDK.

If you have developed your application with Visual Studio you should have configured your project to sign the
APPX package with a PFX certificate. To digitally sign the obfuscated APPX package, you can use the PFX
certificate and enter the following at the command line:

> SignTool.exe sign /v /fd SHA256 /a /f MyAppKey.pfx BabelOut\MyWinStoreApp.appx

The following certificate was selected:


Issued to: xxxxxx
Issued by: xxxxxx
Expires: Wed Jan 08 17:18:01 2014
SHA1 hash: 987275F2AC2E14B935B36EEE02C6480FB23B7842

Done Adding Additional Store


Successfully signed: MyWinStoreApp.appx

Number of files successfully Signed: 1


Number of warnings: 0
Number of errors: 0

Once the APPX package is digitally signed you can run the Windows App Certification Kit to test if the
obfuscated APPX package meets the Windows Store requirements and can be deployed.
155

Android APK Packages

Babel supports obfuscation of Android APK packages build with Xamarin. To obfuscate an APK package
enter at command line the path of the APK package to obfuscate:

babel.exe AndroidApp.apk

Babel Obfuscator will obfuscate all the assemblies inside the package and produce a new APK package in the
BabelOut directory. You can use --take and --skip command line options to set the assemblies to obfuscate.

The obfuscated APK can be re-signed using Babel Obfuscator and entering at command line:

babel.exe AndroidApp.apk --keystore debug.keystore --keypass android --storepass android


--keyalias androiddebugkey

Babel will start the external tool jarsign.exe available with the Java SDK to resign the obfuscated APK.

If you have installed Java and Android SDKs and babel cannot find jarsign.exe and zipalign.exe, please add
path of jarsing.exe and zipalign.exe tools to the system environment variable PATH.

If you want to sign an APK with the MSBuild Babel task, you can use the following APK signing task attributes:

<Babel AndroidSigningKeyAlias="$(AndroidSigningKeyAlias)"
AndroidSigningKeyPass="$(AndroidSigningKeyPass)"
AndroidSigningKeyStore="$(AndroidSigningKeyStore)"
AndroidSigningStorePass="$(AndroidSigningStorePass)"

Cross Assembly Obfuscation with Packages

To enable cross assembly obfuscation and obfuscate all public members used among the obfuscated
assemblies you need to generate and pass map files and use an XML rule file to configure public obfuscation
(see Cross Assembly Obfuscation). This can be accomplished also when obfuscating a package. Just enter at
the command line the switch mapout and Babel will generate for each obfuscated assembly the
corresponding map file to pass as an input to the next obfuscated assembly inside the XAP package:

babel.exe SilverlightRichEdit.xap –-take .*RichEdit –-skip System.* --mapout


-–rules publicRules.xml

Babel can recognize the correct order in which the assemblies must be processed and pass the correct map
files to the currently obfuscated assembly.
156

Advanced Topics
In this section, we’ll examine some advanced Babel usage topics like obfuscation of a Silverlight application
package, signing an assembly with Portable Information Exchange key, and successfully obfuscating
assemblies that target x64 Windows platforms. Following that is a description on how to store MSIL encrypted
method data into an external file instead of a managed resource and use that file for loading encrypted code
at runtime. Another interesting technique is obfuscating the public members of an assembly that will be
referenced in the main application; that is explained in the Obfuscate Multiple Assembly section. Finally, we’ll
give you some hints on how to troubleshoot problems that sometimes occur during the obfuscation process.
157

Satellite Assemblies for Localized Applications

Satellite assemblies are those generated by Visual Studio for projects that contain localized resources.
These localized assemblies contain only resources, no code.

Babel can handle and automatically obfuscate satellite DLLs that are part of an obfuscated executable. You
don’t need to specify them on the command line as inputs. Babel will search for assemblies’ culture-specific
resources located in application directories named after their localized culture names.
For example, the above application directory contains Localization.exe and a set of culture specific folders
each containing the satellite assembly for the related culture given by the folder name.

babel .\Localization.exe

Babel Obfuscator version 9.3.3.0


Copyright (C) 2010-2019 babelfor.NET. All rights reserved.
Process is 64 bit
Processing Localization.exe...
Current directory: 'C:\Projects\Babel\Tests\Resources\Assemblies\Localization'
Analyzing...
Target framework: .NETFramework,Version=v4.0
Obfuscating names...
Loading satellite assembly '.\de-DE\Localization.resources.dll'...
Loading satellite assembly '.\fr-FR\Localization.resources.dll'...
Loading satellite assembly '.\it\Localization.resources.dll'...
Loading satellite assembly '.\it-IT\Localization.resources.dll'...
Writing satellite assembly '.\BabelOut\de-DE\Localization.resources.dll'
Writing satellite assembly '.\BabelOut\fr-FR\Localization.resources.dll'
Writing satellite assembly '.\BabelOut\it\Localization.resources.dll'
Writing satellite assembly '.\BabelOut\it-IT\Localization.resources.dll'
Encrypting strings...
Writing .\BabelOut\Localization.exe

Babel during the processing of the Localization.exe assembly will search for localized resource in each culture
specific folder to align the resources names with the one provided by the main application.
The localized resources are then copied to the output folder alongside the Localization.exe executable.

To prevent the automatic discovering of satellite assemblies you can use the command line option:

babel .\Localization.exe --nosatellite

And babel will not process any satellite assembly.


You can also force to process culture specific satellite assemblies by passing each assembly at command
line:

babel .\Localization.exe --satellite .\de-DE\Localization.resources.dll


--satellite .\fr-FR\Localization.resources.dll
158

PFX Assembly Signing

The Personal Information Exchange (.PFX) file is typically used to sign an assembly so that .NET Framework
can detect if the assembly has been tampered. The signature added to the assembly is generated using an
encryption algorithm that needs a private and a public key. The public key is embedded into the assembly with
the signature and it used by .NET to validate the signature while the private key is used to generate the
signature. The PFX file contains both the private and the public keys so it must not be distributed with the
assembly. Must be kept in a safe place because it identifies your company as the certified source of the
software. No one else can distribute your assembly or modify it giving the same signature without your PFX
file.

If you signed an assembly during the build with a .PFX file, the obfuscation that changed the assembly bits,
invalidates the signature. This means that after obfuscation you need to resign the assembly to get a valid
signature.

Babel Obfuscator can resign the assembly after obfuscation using your original PFX file.
To resign your assembly with Babel from command line, add the following switches:

--keyfile <full path to PFX file> --keypwd <PFX file password>

For example:

--keyfile C:\keys\mykeys.pfx --keypwd mysecretpass

If you are obfuscating from the Babel user interface, you can resign your assembly configuring the PFX file in
the Output panel:

Under Signing, Strong Name Key, browse for your .PFX file. Then press the Set Password button to set the
.PFX file password.

Babel supports assembly re-sign with PFX and Strong Name Key (.SNK) file formats. While the .PFX file
require a password to be used, the SNK file format does not require a password. In case you are using an
SNK file just enter at command line only the switch for the key file. For example:

--keyfile C:\keys\mykeys.pfx

Babel supports PFX files generated with any edition of Visual Studio. If you own a digital certificate PEM file
generated by a certification authority, you can convert to a PFX file valid for signing assemblies using
openssl.exe:

openssl pkcs12 -export -in cert.pem -inkey key.pem -out keys.pfx -keysign
159

Obfuscating x64 Assemblies

Depending on the target platform, the Visual Studio compiler emits the desired CPU architecture into the PE
header. Users of Visual Studio can set the target platform in the build project’s property page. The default
platform is “Any CPU” which indicates that the compiled assembly can run on any version of Windows. When
a managed executable is loaded, Windows examines the PE header to determine whether the application
requires 32-bit or 64-bit CPU architecture to ensure that it matches the computer’s CPU type. Windows
ensures the compatibility of 32-bit applications on 64-bit CPUs with a technology called WoW64 (Windows on
Windows64) that emulates 32-bit instruction sets on a 64-bit CPU, albeit with a performance loss. When the
application architecture is known, Windows loads the framework execution engine Just-In-Time compiler (JIT)
specific to the executable target platform (x86, x64, Itanium). On x64 operating systems, the MSIL code of
assemblies targeting "Any CPU” platform is validated by the .NET Framework runtime before execution.

To protect an assembly from being disassembled by tools like .NET Reflector, Babel can insert into any MSIL
method invalid byte codes that do not correspond to any MSIL op-code instruction (--invalidopcodes). The
resulting assembly is no longer IL verifiable and Windows can execute it only on a WoW64 subsystem.
Suppose that the obfuscated assembly is a DLL referenced by an executable that runs in full 64-bit
environment. When the runtime tries to load the DLL obfuscated with invalid opcodes, it checks the CPU JIT
requirements, and because they do not match, it throws an InvalidProgramException exception. The only way
to generate obfuscated DLLs or executables fully compatible with x64 is to disable the injection of invalid
opcodes during obfuscation.

Customize MSIL Encryption

With MSIL encryption the method code is hidden in a .NET Framework DynamicMethod object compiled at
runtime with encrypted code stored in a managed resource. The original method is reduced to a call to the
compiler engine stub. The DynamicMethod objects compiled with encrypted MSIL code are executed and
then discarded. Moreover, once compiled, they cannot be modified. This makes the reverse engineering of
encrypted methods very difficult. Commonly, the encrypted code is embedded into the assembly resources,
but Babel can also store the encrypted MSIL code in standard files that can be loaded at runtime by the
dynamic method compiler, that is embedded into the obfuscated assembly. This means that encrypted
methods are stripped out from the assembly and serialized into an external file. The obfuscated assembly
contains only calls to the compiler stub and there is no way to get the original method code without the
encrypted file. Those files can be used to implement a custom licensing method or even stored in a database
or secure store and retrieved by the application when required.

To configure the generation of encrypted files, Babel needs to know the encrypted source name and the
method that should be called to retrieve the encrypted data. The former comes from XML rules files; the latter
from custom attributes. We have already seen in the MSIL Encryption section the XML properties available for
the “msil encryption” feature: Cache, MinInstructionCount, MaxInstructionCount and Source. Source contains
a string value that is the name of the encrypted data source associated with all the methods encrypted by the
rule. Consider the following XML rule:

<Rule name="Rgb" feature="msil encryption" exclude="false">


<Target>Methods</Target>
<Pattern>Utilities.Rgb::*</Pattern>
<Properties>
<Cache>true</Cache>
<Source>rgb</Source>
<MinInstructionCount>5</MinInstructionCount>
</Properties>
<Description>Encrypt methods of Rgb class.</Description>
</Rule>

This rule tells Babel to encrypt all the Rgb class methods that contain at least five MSIL instructions and to
assign the source name rgb to the encrypted data. Babel will generate in the output folder a file named rgb.eil
160

(where .eil stand for Encrypted IL) that contains the encrypted code that will be used by the dynamic method
compiler at runtime to generate the Rgb class methods.

Once you have the encrypted data files you need to tell Babel the method that will be used to retrieve the
encrypted stream at runtime. This can be done by using the custom attribute
System.Reflection.ObfuscationAttribute on an internal static method that takes the source name string as a
parameter and returns the encrypted MSIL System.IO.Stream object. The
System.Reflection.ObfuscationAttribute must specify the constructor-named parameter Feature as "msil
encryption get stream".

/// <summary>
/// Given the MSIL source name, returns the encrypted code stream.
/// </summary>
/// <param name="source">The name that identifies the source
/// stream.</param>
/// <returns>Encrypted MSIL source stream.</returns>
[Obfuscation(Feature="msil encryption get stream")]
internal static Stream GetSourceStream(string source)
{
}

At runtime, when an encrypted method of the Rgb class is called, the dynamic method compiler recognizes
that the encrypted method data is associated with an external source instead of the assembly-embedded
resource, and it will make a call to the method GetSourceStream with source argument equal to “rgb” to
retrieve the encrypted Stream object.

Cross Assembly Obfuscation

The obfuscation process itself can only rename the internally visible assembly symbols, leaving the public
members untouched. Otherwise the runtime execution of assemblies that consume the obfuscated types will
be compromised.

Babel can obfuscate public and internally accessible members in multiple assemblies, fixing the name of
obfuscated symbols referenced in each assembly.

Cross assembly obfuscation is made possible by means of map files. Map files are XML files produced as
output from the obfuscation process and contain all the associations between original and obfuscated symbol
names. When using map files, it is possible to recover the original symbol names from the obfuscated ones.
Map files should not be deployed with the obfuscated application under any circumstances. Keep them
private.

Consider the following example of a managed application (Calculator.exe) that references two assembly
libraries: Algorithms.dll and Math.dll. Suppose that Algoritms.dll references Math.dll also and that Math has
InternalsVisibleTo attribute for the Algorithm assembly so that this one can access internal types declared in
Math. The reference graph is represented as follows:
161

Calculator.exe

Algorithms.dll Math.dll
InternalsVisibleTo[Algorithm]

The two referenced assemblies: Algorithms.dll and Math.dll are general-purpose assemblies, used in several
other projects. We want to obfuscate the entire project without merging the referenced libraries, as they are
used by other applications as well and not just Calculator.exe. We want to keep the deployed package size as
small as possible, and exclusion of referenced assemblies will assist with that. Algorithms and Math
assemblies contain many public classes, so to effectively obfuscate the whole project we’d like to mangle
public members as well. Babel can address this issue by generating an obfuscation map file for each
referenced assembly that will have its public member obfuscated and use those map files when obfuscating
the main application assembly or every other assembly with references back to public obfuscated assemblies.

To set up the obfuscation process, first we need to tell Babel to obfuscate all public symbols of Math.dll and
Algorithms.dll assemblies. This can be done by inserting into the source code the following assembly-level
custom attribute declaration:

[assembly: System.Reflection.ObfuscateAssembly(true)]

This attribute provides a way to configure Babel to obfuscate public symbols without using external
configuration files. Setting the Boolean constructor parameter to true specifies that the assembly is private so
that public member names can be safely obfuscated. If you don’t want to change the source code you may
even create an XML rules file that forces the obfuscation of public member names:

<?xml version="1.0" encoding="utf-8"?>


<!--
publicRules.xml
-->
<Rules version="2.0">
<Rule name="Obfuscate public" exclude="false">
<Access>Public</Access>
<Pattern isRegEx="false">*</Pattern>
<Description>Obfuscate all public symbols.</Description>
</Rule>
</Rules>

Once we configure obfuscation of public symbols, we are ready to start babel.exe, including in the command
line the option --mapout whenever we need to produce an output map file, and --mapin for each assembly that
has a reference to a previously obfuscated assembly. We need to start from the assemblies that have no
references to other obfuscated one. Returning to our Calculator example we can enter into a DOS shell the
following commands:

> babel.exe Math.dll --rules publicRules.xml –-mapout

> babel.exe Algorithms.dll --rules publicRules.xml –-mapout


162

--mapin Math.dll.map.xml

> babel.exe Calculator.exe -–mapin Math.dll.map.xml --mapin Algorithms.dll.map.xml

Using this obfuscation feature it is possible to achieve a high level of renamed symbols, comparable to the
level obtained by merging referenced assemblies.

Setup from The User Interface


When the application to be configured for cross assembly obfuscation is made by many components,
choosing the correct obfuscation order can be cumbersome. The Babel Obfuscator user interface in this case
can help you to setup the cross-assembly obfuscation with few clicks.

Just Drag & Drop in the Input Grid all the assemblies you want to cross obfuscate. Then right click in the Input
Grid and from the drop-down menu choose Setup Public Obfuscation.

Babel will sort the assemblies according their references, configuring mapping options and public obfuscation
rules to enable cross assembly obfuscation.

Note that you can cross obfuscate third-party assemblies when they are not strong named or if you can
access the original key pair to resign the assembly. If you cannot access the original sign key pair you must
exclude the assembly from public obfuscation. To exclude an assembly from public obfuscation just right click
the Input Grid column header and from the drop-down menu select the “Colum Chooser”. The Customization
dialog will popup.

Drag & Drop the Rename Public and Public Key Token fields into the Input Grid.
Now you can uncheck the Rename Public checkbox for each third-party assembly having the Public Key
Token not null. By unchecking the Rename Public field Babel will remove the obfuscation rule created to
rename all public symbols exposed by the third-party assembly.
163

Once you run the obfuscation, check the output warnings. You should care about the OB0003 warning. This
warning appears in rare occasions. If this warning is present for a given assembly, you should manually
create a renaming rule to prevent the renaming of the member indicated:

Warning [OB0003]: The virtual property: 'double Math.Interfaces.IAlgorithm::Id()' defined into referenced
module: 'Algorithms.dll' cannot be obfuscated: Cross interface definition dependency.
Please add an obfuscation rule to prevent the renaming of the symbol.

To fix the OB0003 warning open the Edit Rule panel for the Algorithms.dll assembly and search in the object
browser for the Interfaces.IAlgorithm type. Then right click the Id property and from the drop down menu
choose:

Add Rule > Renaming > Disable Renaming

This rule will prevent the renaming of the property Math.Interfaces.IAlgorithm::Id indicated in the OB0003
warning message fixing the cross assembly obfuscation.

Babel Obfuscator Plugins

Babel Obfuscator Enterprise and Company editions, support custom plug-ins.

With a custom plugin, you can:

• Create your custom string encryption algorithm


• Create your custom value encryption algorithm
• Merge custom code to your assembly
• Define obfuscation rules by querying the assembly metadata
• Change the assembly code
• And much more…

To create a custom plugin that can be used by Babel Obfuscator, you have to write a .NET assembly class
that derives from BabelPluginBase and implement the services you want to handle. The BabelPluginBase
class and all the types you can use inside a plugin are defined in the babel.exe assembly. This assembly must
be added to the list of references of your plugin project.

Code Samples
There are several Babel plugins, source code included, already available on GitHub

https://github.com/babelfornet/BabelPlugins.

If you want to implement your custom plugin, you might be interested to look at these sample plugins. To
download the solution containing all the plugin projects, enter the following git command:
164

git clone https://github.com/babelfornet/BabelPlugins.git

We will update this area to add more plugins in the future.

Custom String Encryption


A Babel plugin can provide a custom string encryption algorithm that Babel can use instead of the standard
XOR and HASH algorithms. To provide a custom string encryption the plugin should register a class that
implement the IBabelStringEncryptionService interface.

The IBabelStringEncryptionService exposes to Babel the following methods and properties:

1. An encryption routine that will be called during obfuscation to encrypt strings

StringDecryptionInfo Encrypt(string source);

The method returns a StringDecryptionInfo object. This encrypted string will be stored into the code
and decrypted at runtime.

2. A method inside the target assembly used at runtime to decrypt strings

MethodDef DecryptMethod { get; }

3. The number of iterations the Encrypt method should be called for a given string

public int Iterations { get; }

The DecryptMethod must be internal static and provide the decryption logic for the string encrypted by the
plugin. This method is called at runtime to decrypt the encrypted string stored into the assembly. The decrypt
method code can be already present into the target assembly or it can be merged by the plugin.

Custom Value Encryption


In a very similar way, the plugin can register a class that implements the interface
IBabelValueEncryptionService. This interface is used by Babel to plug in your custom value encryption
algorithm.

In this case you have to provide an encryption routine to encrypt each value type (Int32, Int64, Single, Double)
or Array stored in the assembly and a related method, called at runtime, to decrypt the encrypted value.

Encryption routines:

int? EncryptInt32(int value);


int? EncryptInt64(long value);
int? EncryptSingle(float value);
int? EncryptDouble(double value);
byte[] EncryptArray(Array array);

The encryption routines get the value to encrypt and return an integer that will be passed to the related
decryption routines at runtime. The EncryptArray routine get an Array object to encrypt and return the byte[] of
the encrypted array. If any of the encryption routines return a null reference, the value passed will not be
encrypted.

The plugin should also provide the decryption methods inside the assembly that Babel will call at runtime to
decrypt the encrypted values or arrays:

MethodDef DecryptDoubleMethod { get; }


MethodDef DecryptInt32Method { get; }
MethodDef DecryptInt64Method { get; }
MethodDef DecryptSingleMethod { get; }
165

MethodDef DecryptArrayMethod { get; }

If one of the above properties return a null reference, the relative value type will not be part of the encryption
process. For example, if the plugin does not provide any method to decrypt doubles:

public MethodDef DecryptDoubleMethod


{
get
{
return null;
}
}

The EncryptDouble(double value) method will not be called during the obfuscation process and double values
will not be encrypted.

The decryptions routines must have the following signature:

internal static Int32 DecryptInt32(int value);


internal static Int64 DecryptInt64(int value);
internal static Single DecryptSingle(int value);
internal static Double DecryptDouble(int value);

internal static Array DecryptArray(byte[] array);

Where the int value passed to each routine at runtime, is the value that the encrypt routines returned during
the obfuscation process for a given Int32, Int64, Single or Double. The DecryptArray method takes the
encrypted byte array retuned by the EncryptArray routine for a given Array object.

Merging Code
To implement your custom string or value algorithm you should provide the decryption methods that are called
at runtime inside the target assembly. Generally, those methods are not part of the target assembly so you
might want to merge your decryption code during the obfuscation process.

To merge your custom decryption routines, you can use Babel.AssemblyDef methods to compile and merge
CSharp code. Override OnBegin method of BabelPluginBase class to get the assembly target object before
the entire obfuscation process begins and add your custom string decryption logic:

public override void OnBegin(AssemblyDef assembly)


{
Logger.Write("Begin processing assemly {0}", assembly.FullName);

AssemblyDef stringDecrypter = AssemblyDef.Compile(


" using System; " +
" using System.Text; " +
" " +
" class StringDecrypter " +
" { " +
" public static string Decrypt(string source) " +
" { " +
" if (source.Length == 0) " +
" return \"\"; " +
" " +
" return Encoding.UTF8.GetString(Convert.FromBase64String(source)); " +
" } " +
" } "
);

assembly.Merge(stringDecrypter);
166

var decryptMethod = target.Find<MethodDef>("StringDecrypter::Decrypt.*", true);

The decryptMethod is the method that will be returned by the interface method
IBabelStringEncryptionService.DecryptMethod : MethodDef.

Check out the plugins at babelfor.NET for more complex samples.


167

Loading Plugins
Babel can accept a list of plugin files at command line.
To specify one or more plugin files at the babel.exe command line, you can use the --plugin switch followed by
the full path to the plugin file:

babel.exe MyTarget.exe --plugin CustomPlugin1.dll --plugin CustomPlugin2.dll

It is possible to define additional plugin arguments using the switch --argument:

babel.exe MyTarget.exe --plugin CustomPlugin1.dll --plugin CustomPlugin2.dll


--argument arg1=value1 --argument arg2=value2

If you are using the Babel Obfuscator user interface, you can specify a plugin for given target assembly, in the
Input Grid, by selecting the Plugins tab under the obfuscation target, and browsing for the plugin file.
168

If the plug-in accepts input arguments, an edit icon is shown next to the plugin.

By pressing the edit icon, a popup dialog will be displayed where the user can enter the input values for each
plugin argument.

The OK button will store the arguments to the obfuscation project for the selected plugin. By pressing the
Cancel button, the changes made to the arguments will be discarded.
169

Using Plugins in Babel Task


If you are using the MSBuild Babel task, you can specify a list of plugins by adding the Plugins property to the
Babel task as follow:

<UsingTask TaskName="Babel" AssemblyName="Babel.Build, Version=9.3.3.0, Culture=neutral,


PublicKeyToken=138d17b5bd621ab7" />

<Target Name="AfterBuild">
<ItemGroup>
<BabelPlugin Remove="@(BabelPlugin)"/>
<BabelPlugin Include="DesEncrypt.dll"/>
<BabelPlugin Include="LicenseInjector.dll"/>
</ItemGroup>
<Babel InputFile="$(TargetPath)"
OutputFile="$(TargetPath)"
ObfuscateTypes="true"
ObfuscateEvents="true"
ObfuscateMethods="true"
ObfuscateProperties="true"
ObfuscateFields="true"
VirtualFunctions="true"
StringEncryption="custom"
Plugins="@(BabelPlugin)"
PluginsArguments="arg1=value1;arg2=value2"
/>
</Target>

Plugin arguments can be specified for all plugins by using the PluginArguments property of the Babel task.
The list of plugin argument is represented by a sequence of key value pairs separated by a semicolon.

PluginsArguments="minStringLength=3;minHashStringLength=15;extraControlFlow=true"
170

Debugging a Plugin
To debug your plugin in Visual Studio, open the plugin project settings and choose the Debug tab. Then under
Start Action select Start external program and browse for babel.exe:

Then enter the command line arguments passing the full path the target assembly, the plugin file name and
additional command line switches:

D:\Projects\AcmeDataMining\bin\Debug\Acme.exe --plugin DesEncrypt.dll --string custom

By pressing F5 you can start babel.exe and hit breakpoints in the plugin code.
171

Obfuscation Guidelines
This paragraph will give you a list of useful tips to protect better your application using Babel Obfuscator.

1. Consider declaring as many types as possible internal (VB Friend): Public types and methods
that are externally visible will not be renamed because they will be potentially used by other
assemblies. Internal (or Friends for VB) declared types are accessible from within the assembly and
are not visible to external assemblies so they can be safely obfuscated.

2. Enable always the Agent: The Agent can help you to avoid common obfuscation problems that
sometimes cause the obfuscated application to crash. It’s also useful to look at the output produced
by the Agent when you need to fine tune your XML rule files.

3. Use hash algorithm when encrypting strings: This will encrypt your strings binding the encrypted
data to strong name signature.

4. Enable dead code removal: At least this will spotlight unused method and give you some hint to
refactoring your code.

5. Do not MSIL encrypt too many methods: MSIL encryption is a powerful protection feature, but it
can slow down significantly the obfuscated application. Encrypt only those methods that run a limited
number of times and contains code that you want to secure.

6. Encrypt resource when necessary: resource encryption can hide all the embedded resource into
your assembly, but it comes at a cost of decryption during execution. This will increase the time
needed by your application to access resources the first time.

7. Consider the environment your application is targeting: If your application is targeting x64
platform, don’t use invalid op-codes option because it will cause your application to run on WOW64.

8. Sign with strong name your assemblies: Babel bind encrypted data to assembly strong name and
insert custom code to detect data tampering.

9. Run peverify.exe /MD on the obfuscated assembly: This tool can tell you if the metadata of your
obfuscated application is verifiable.

10. Check the Babel command line output: The Babel output can give you a lot of information about
the obfuscation process and display warnings that should be always reviewed.

11. Test your obfuscated application: Obfuscation might break your code. To avoid any unexpected
behavior at run-time, perform all the necessary tests on the obfuscated assemblies.
172

Troubleshooting a Broken Application

Every effort has been made to avoid runtime problems caused by obfuscation. But occasionally obfuscation
can break an application or cause it to function in an unexpected manner. In this situation there are several
things that can be done. If you run a full obfuscation that involved renaming, string encryption, control flow
obfuscation, MSIL encryption and so on, try to lower the obfuscation level by running Babel with fewer tasks to
perform.

For instance, consider disabling only string encryption, and then check whether the obfuscated application is
fixed. If not, disable another phase like MSIL encryption, and then check again. If the problem persists, you
can disable the remaining options one by one. For example, to disable type obfuscation, enter in the
command line the option –notypes or its short form –not. If this fixes the application, you will know that the
problem is with type renaming. Of course, you can go on and disable all the other renaming options: -notmf
command will disable the renaming of types, methods and fields, leaving only events and properties
obfuscation. When you find the cause of the problem, you can refine your search by running the peverify.exe
tool on the obfuscated target. The hints that come from peverify should be enough to spot the cause of the
error and give you the necessary information to make a custom XML rule to avoid the obfuscation of the faulty
symbol.

There is another possibility of course: you have found a bug in Babel. In this case, contact email support:

support@babelfor.net

Send all the useful information you can, such as:

 The operating system you are running on and processor architecture (x86 or x64)
 Babel version and command line used
 Babel log output (use the --logfile command line option)
 Peverify.exe output
 Steps required to reproduce the issue

The more information you send, the more likely it will be that we can reproduce and fix the problem. If
possible, you should also send the faulty assembly or, if this is not possible, a sample Visual Studio project
that reproduces the same issue. This last item is not always possible, but it would help us tremendously in
solving the problem.
173

Appendix A
Warning Codes

The following table shows the list of warning codes and messages.
The codes can be used with command line option --nowarn.

Code Message
CF0001 Unknown invalid op-code mode: '{0}'.

EI0001 Missing key information, the target assembly will not be resigned.
EI0002 Could not sign assembly {0}: {1}

EM0001 Return type {0} not supported at {1}


EM0002 Methods with pointer parameters are not supported at {0}
EM0003 Methods with ref or out parameters are not supported at {0}
EM0004 Generic instance method inline tokens are not supported at {0}
EM0005 Inline metadata tokens are not supported at {0}
EM0006 Bad inline token type.
EM0007 Unknown metadata signature calling convention.
EM0008 Generic open types are not supported at {0}
EM0009 Generic parameter types are not supported at {0}
EM0010 Type {0} not supported.
MG0001 Found duplicated type {0} in merged assembly '{1}'
MG0002 Referenced assembly '{0}' has a reference to the merged assembly '{1}'
MG0003 Resource data '{0}' into {1} has already been added.
MG0004 {0} (Could not resolve… generic warning message)
MG0005 Merging referenced assembly {0} of different version {1}. The expected assembly version is
{2}. The merged assembly might not be working properly.
MG0006 The assembly '{0}' has already been merged.
MG0007 The type '{0}' defined in '{1}' was not found in merged scope '{2}'.
MG0008 Merge of mixed mode assembly is not supported: '{0}'.
MG0009 The demo version of '{0}' assembly cannot be merged. Please use the retail component.

OB0001 Missing key information, could not sign resource assembly '{0}'
OB0002 The {0} named '{1}' defined into referenced assembly {2} should not be obfuscated.
OB0003 The following virtual members:
{0}
cannot be obfuscated cause {1}.
Please add an obfuscation rule to prevent the renaming of the symbol.
OB0004 The Unicode character set provided is not valid to rename {0} symbols{1}. The ASCII
character set will be used instead.
OB0005 Obfuscation rules are preventing renaming of the following public members:
{0}
cause {1}.
OB0006 Found rule conflict for the following symbols: {0}.{1}The {2} prevents symbol renaming, while
{3} requires to rename. The symbols will not be renamed.
OB0007 Name conflict for referenced member '{0}'
OP0001 Could not remove enum(s) '{0}'. Method '{1}' has a duplicate.
OP0002 {0} method '{1}' cannot be inlined.

PR0001 The target assembly has already been obfuscated, some issues might happen during
obfuscation or at runtime.
PR0002 {0} warning: missing {1} string method.
174

PR0003 Suppressing MSIL disassembler option is not supported on .NET Framework {0} assemblies.
PR0004 Suppress MSIL disassembler (ildasm.exe) option is not supported.
PR0005 The target assembly has already been obfuscated, babel will exit now without performing any
further processing.
PR0006 NOT USED
PR0007 String algorithm '{0}' is not supported. Algorithm '{1}' will be used instead.
PR0008 Emit invalid op-codes option is not supported on {0} assemblies.
PR0009 The reference "{0}" has a higher version '{1}' than the version '{2}' in the current target.
PR0010 The assembly "{0}" is already present in the list of references.
PR0011 Dynamic proxy call option is not supported on {0} assemblies.
PR0012 Resource encryption is not supported on {0} assemblies.
PR0013 MSIL encryption is not supported on {0} assemblies.
PR0014 Assembly embedding is not supported on {0} assemblies.
PR0015 Suppress reflection option is not supported on {0} assemblies.
PR0016 Invalid ObfuscationAttribute at {0}: {1}

RU0001 Feature '{0}' has an unknown property name '{1}'


RU0002 Rules file unknown node {0} at line {1}, position {2}, node {3} '{4}'
RU0003 Rules file unknown attribute at line {0}, position {1}, attribute {2}='{3}'
RU0004 Unknown feature '{0}'

SE0001 Encryption string algorithm {0} could not encrypt string '{1}': {2}

W00000 This is an evaluation version, the obfuscated assembly will no longer work after {0}
W00001 Could not find debug symbols for {0}
W00002 Cannot parse {0} resource stream '{1}': {2}.
W00003 {0} resource stream '{1}'. Cannot resolve the following members: {2}
W00004 Obfuscation Agent is disabled.
W00005 Debug symbols not loaded: {0}.
W00006 The member name '{0}' defined by the assembly '{1}' has been renamed according to the
information contained inside the XML map file. Please remove this member from the '{2}'
resource.
W00007 Could not delete {0} directory: {1}
W00008 The assembly '{0}' was resolved to '{1}'
W00009 Could not find method: '{0}'.
W00010 Could not use method '{0}' as module initializer. The method must be a static method without
parameters.
W00011 The referenced assembly '{0}' full name differs from the loaded map file '{1}'.
W00012 Invalid map file assembly name '{0}': {1}
W00013 Could not resolve assembly '{0}'.
W00014 Error getting symbols from {0}: {1}
W00015 Cannot find overridden methods of '{0}': {1}
W00016 Could not sign assembly {0}: {1}
W00017 The debug symbol file {0} do not match assembly {1}
W00018 {0} assembly resolver failed to resolve assembly {1}: {2}
175

Unicode Character Ranges

0020 — 007F Basic Latin 2150 — 218F Number Forms


00A0 — 00FF Latin-1 Supplement 2190 — 21FF Arrows
0100 — 017F Latin Extended-A 2200 — 22FF Mathematical Operators
0180 — 024F Latin Extended-B 2300 — 23FF Miscellaneous Technical
0250 — 02AF IPA Extensions 2400 — 243F Control Pictures
02B0 — 02FF Spacing Modifier Letters 2440 — 245F Optical Character Recognition
0300 — 036F Combining Diacritical Marks 2460 — 24FF Enclosed Alphanumeric
0370 — 03FF Greek and Coptic 2500 — 257F Box Drawing
0400 — 04FF Cyrillic 2580 — 259F Block Elements
0500 — 052F Cyrillic Supplementary 25A0 — 25FF Geometric Shapes
0530 — 058F Armenian 2600 — 26FF Miscellaneous Symbols
0590 — 05FF Hebrew 2700 — 27BF Dingbats
0600 — 06FF Arabic 27C0 — 27EF Miscellaneous Mathematical Symbols-A
0700 — 074F Syriac 27F0 — 27FF Supplemental Arrows-A
0780 — 07BF Thaana 2800 — 28FF Braille Patterns
0900 — 097F Devanagari 2900 — 297F Supplemental Arrows-B
0980 — 09FF Bengali 2980 — 29FF Miscellaneous Mathematical Symbols-B
0A00 — 0A7F Gurmukhi 2A00 — 2AFF Supplemental Mathematical Operators
0A80 — 0AFF Gujarati 2B00 — 2BFF Miscellaneous Symbols and Arrows
0B00 — 0B7F Oriya 2E80 — 2EFF CJK Radicals Supplement
0B80 — 0BFF Tamil 2F00 — 2FDF Kangxi Radicals
0C00 — 0C7F Telugu 2FF0 — 2FFF Ideographic Description Characters
0C80 — 0CFF Kannada 3000 — 303F CJK Symbols and Punctuation
0D00 — 0D7F Malayalam 3040 — 309F Hiragana
0D80 — 0DFF Sinhala 30A0 — 30FF Katakana
0E00 — 0E7F Thai 3100 — 312F Bopomofo
0E80 — 0EFF Lao 3130 — 318F Hangul Compatibility Jamo
0F00 — 0FFF Tibetan 3190 — 319F Kanbun
1000 — 109F Myanmar 31A0 — 31BF Bopomofo Extended
10A0 — 10FF Georgian 31F0 — 31FF Katakana Phonetic Extensions
1100 — 11FF Hangul Jamo 3200 — 32FF Enclosed CJK Letters and Months
1200 — 137F Ethiopic 3300 — 33FF CJK Compatibility
13A0 — 13FF Cherokee 3400 — 4DBF CJK Unified Ideographs Extension A
1400 — 167F Unified Canadian Aboriginal 4DC0 — 4DFF Yijing Hexagram Symbols
1680 — 169F Ogham 4E00 — 9FFF CJK Unified Ideographs
16A0 — 16FF Runic A000 — A48F Yi Syllables
1700 — 171F Tagalog A490 — A4CF Yi Radicals
1720 — 173F Hanunoo AC00 — D7AF Hangul Syllables
1740 — 175F Buhid D800 — DB7F High Surrogates
1760 — 177F Tagbanwa DB80 — DBFF High Private Use Surrogates
1780 — 17FF Khmer DC00 — DFFF Low Surrogates
1800 — 18AF Mongolian E000 — F8FF Private Use Area
1900 — 194F Limbu F900 — FAFF CJK Compatibility Ideographs
1950 — 197F Tai Le FB00 — FB4F Alphabetic Presentation Forms
19E0 — 19FF Khmer Symbols FB50 — FDFF Arabic Presentation Forms-A
1D00 — 1D7F Phonetic Extensions FE00 — FE0F Variation Selectors
1E00 — 1EFF Latin Extended Additional FE20 — FE2F Combining Half Marks
1F00 — 1FFF Greek Extended FE30 — FE4F CJK Compatibility Forms
2000 — 206F General Punctuation FE50 — FE6F Small Form Variants
2070 — 209F Superscripts and Subscripts FE70 — FEFF Arabic Presentation Forms-B
20A0 — 20CF Currency Symbols FF00 — FFEF Halfwidth and Fullwidth Forms
20D0 — 20FF Combining Diacritical Marks FFF0 — FFFF Specials
2100 — 214F Letterlike Symbols
176

Index
DevOps; 145
. Disgregate Removal; 20; 21; 108
Dynamic Proxy Calls; 101
.NET Micro Framework; 17; 19; 21; 28; 139 DynamicMethod; 93; 94; 159
.NET Micro Framework and nanoFramework; 139
.NET Reflector; 13; 17; 52; 90; 91; 99; 159
.pfx; 56; 57 E
Embed Assemblies; 78
A EncrypString; 97
encrypt; 52; 53; 65; 69; 78; 79; 92; 93; 94; 95; 96; 97; 98; 99;
Activating Instrumentation; 111 120; 121; 126; 159; 170
Advanced Topics; 156 Enhanced Control Flow Obfuscation; 89
Any CPU; 159 extended help; 45
APPX; 19; 28; 36; 44; 152; 154
Assembly Merge; 49
Assembly Merging; 18; 20; 22; 28; 76 F
assembly re-sign; 158
automated build; 13; 29 FAQ; 26
Automatic Class Sealing; 105 Feature Matrix; 19

B H
Babel Task; 117; 118; 130; 135 hash; 96
babel.exe.config; 45; 58; 106; 107; 153; 154 HASH Algorithm; 96

C I
Cache; 94 ILDASM; 13; 17; 18; 53; 90; 91
Code Instrumentation; 110 ILMerge; 49
Code Optimizations; 61; 108 inline expansion; 55; 108; 109
Command Line; 17; 20; 23; 28; 44; 61 Inline Expansion; 20; 21; 108; 109
Compact Framework; 17; 19; 21 Input Files; 56
CompilerGeneratedAttribute; 106 Intellisense; 144
compress; 47; 78; 79; 99; 153 Invalid Op-Codes; 90
Configuration File; 58
Control Flow Obfuscation; 17; 19; 21; 23; 28; 51; 61; 87; 88
Cross Assembly Obfuscation; 155; 160 L
Custom Attributes; 71
custom string encryption; 97 License File; 27
Custom String Encryption; 97 Licensing; 23; 24; 26; 48

D M
Dead Code Removal; 105 MAC OSX Setup; 32; 33
DebuggerBrowsableAttribute; 106 MaxInstructionCount; 94
DebuggerDisplayAttribute; 106 Metadata; 13; 28; 65; 105
DebuggerHiddenAttribute; 106 Metadata Optimizations; 105
DebuggerNonUserCodeAttribute; 106 MinInstructionCount; 94
DebuggerStepThroughAttribute; 106 module initializer; 55
DecryptString; 97
177

MSBuild; 13; 17; 20; 23; 28; 29; 30; 36; 56; 117; 118; 119; strong name; 39; 56; 158; 170
120; 121; 122; 123; 130; 134; 135; 136; 137; 138; 139; 144 Strong Named Assemblies; 157
MSIL Encryption; 13; 17; 19; 21; 28; 52; 93 System.Enum Types Removal; 107
Multi user; 24 System.Reflection.ObfuscateAssemblyAttribute; 71
System.Reflection.ObfuscationAttribute; 71

O
T
Obfuscation Agent; 62
Obfuscation Tips; 170 Tampering Detection; 102
ObfuscationAttribute; 71; 93; 159 Task Attributes; 123
Optimizations; 104 ToolPath; 120
Output Files; 56 Tracing; 112
Overloaded Renaming; 19; 21; 28; 83 Tracing Walkthrough; 112
Troubleshooting a Broken Application; 171

P
U
performance; 79; 92; 159
peverify.exe; 171 Unicode Character Ranges; 174
Phases; 61 Unwanted Attributes; 106
Plugins; 163 User Interface; 17; 23; 30; 35
Post Build Event; 135
private assembly; 71
Project File; 135 V
Visual Studio; 2; 12; 14; 17; 20; 23; 29; 112; 121; 130; 131;
Q 134; 135; 136; 138; 139; 140; 144; 154; 157; 158; 171
Visual Studio integration; 134
quick rule definition; 47

W
R
Warning Codes; 172
Renaming; 49; 80 Windows App Certification Kit; 154
Resource encryption; 99 Windows on Windows64; 159
reverse engineer; 13 Windows Phone; 17; 19; 21; 28; 140
Rules File; 64 Windows Runtime; 17; 19; 21; 28; 138
Windows Store; 138
WPF; 20; 24; 75; 77; 80; 84; 99
S
Satellite Assemblies; 157 X
serializable types; 63
Settings; 38; 84 x64 bit; 31; 91
Setup; 31 Xamarin Forms; 141
SHA256; 154 XAML and BAML Obfuscation; 84
SignTool.exe; 154 XAP; 18; 23; 28; 36; 44; 46; 47; 78; 84; 123; 124; 137; 140;
Silverlight; 17; 18; 19; 20; 21; 23; 24; 28; 75; 77; 78; 80; 84; 152; 153; 154
85; 96; 101; 137; 140; 153; 156 XapSkipList; 153
SimpleTrace Project; 112 Xbox 360; 17; 19; 28
Single user; 23 XNA Framework; 17; 19; 28
Source property; 159 xor; 96
Stack Trace; 42 XOR Algorithm; 96
String Encryption; 17; 19; 21; 28; 96; 97

You might also like