Assembly can be easily debugged in Debug
project configuration when no obfuscation takes place.
But you may want to debug your assembly in Release
configuration when obfuscation does take place.
There are not much reasons to do so, however sometimes it may be a life-saver.
That's why debugging after obfuscation is supported by Eazfuscator.NET.
The debugging feature of Eazfuscator.NET is turned off by default to allow faster builds and better optimizations. If you want to enable debugging then please follow the instructions below:
Instructions on enabling debug support for an output assembly
- Open obfuscatable project inside the IDE
-
Add new source file to the project and
call it
ObfuscationSettings.cs
(for C#) orObfuscationSettings.vb
(for Visual Basic .NET). You may prefer to use another name instead ofObfuscationSettings.cs
orObfuscationSettings.vb
-
Fill
ObfuscationSettings.cs
with the following content (C#):using System; using System.Reflection; [assembly: Obfuscation(Feature = "debug", Exclude = false)]
For Visual Basic .NET, fill
ObfuscationSettings.vb
with the following content:Imports System Imports System.Reflection <Assembly: Obfuscation(Feature:="debug", Exclude:=False)>
Note | |
---|---|
Debugging experience may slightly suffer if used together with code control flow obfuscation feature. |
Eazfuscator.NET changes assembly contents during obfuscation, so the debugging information gets out of sync when no special provisions are made. If the input assembly contains an applied "debug" attribute that was discussed above then Eazfuscator.NET takes care of debugging information and transforms it according to the applied assembly changes. That's why the debug information is always in sync when debug support is on for a given assembly.
The debug information is stored in .pdb
file which is located near the assembly.
For example, MyAssembly.dll
may have a corresponding MyAssembly.pdb
file.
When you start a debug session the debugger tries to find the .pdb
files for all loaded assemblies.
If the right .pdb
file is found then you are able to set breakpoints and watch variables in debugger.
.pdb
files store the following information:
- The names of source files (including their full paths)
- Line numbers
- Associations between IL instruction offsets, line numbers and source files
The names of source files can be used to find the original class names
when corresponding .pdb
file is available to a reverse-engineer.
So please use .pdb
files with care — they can weaken the protection strength.
The security of .pdb
files can be improved by using secure debugging.
The debugging directive provides a basic experience by default. This is enough to quickly step through your code and spot exceptions. You may also opt in to the improved security and readability of debugging information. In order to do that, please read the notes below.
The full notation of a custom attribute for debugging has the following form:
[assembly: Obfuscation(Feature = "debug [flags]", Exclude = false)]
where [flags]
is an optional enumeration of flags separated by spaces.
The list of available flags is presented in the table below.
Table 4.8. The list of flags for debugging directive
Flag | Description |
---|---|
secure | Activates secure debugging |
relative_file_paths |
Instructs to produce relative file paths in resulting .pdb file
|
nonintrusive | Allows to perform nonintrusive debugging sessions to catch hard-to-reproduce bugs sensitive to time, size or other nonlinear factors |
Debug information can be a weak point in security of an obfuscated application.
But what if you want to get the line numbers and file names without compromising the security?
Well, this goal is easily achievable. All you have to do is to supply [secure]
flag to an obfuscation attribute like so in C#:
[assembly: Obfuscation(Feature = "debug [secure]", Exclude = false)]
or in VB.NET:
<Assembly: Obfuscation(Feature:="debug [secure]", Exclude:=False)>
What happens then?
Eazfuscator.NET starts to encrypt source file names in .pdb
file in the very same way as it does for other items such as class and method names.
So, whenever you have symbol names encryption set up for your assembly
it will be also applied to the content of .pdb
file.
Tip | |
---|---|
If you do not want to apply symbol names encryption to the whole assembly then just provide a password as shown below: [assembly: Obfuscation(Feature = "debug [secure] with password XXXXXX", Exclude = false)] Change XXXXXX with your password. Keep the password in secret. |
Obviously, the secure debugging makes stepping through the code impossible as a debugger no longer knows how to find the source files:
their names are now encrypted and debugger has no means to decrypt them.
This is a little sacrifice for the big benefit: all logged exceptions will contain the full information you need in an encrypted and safe form.
Class names, method names, argument names, file names and line numbers are all there to help you to precisely locate the problematic code.
And now you can safely distribute .pdb
files to your customers without the risk of security breach.
Tip | |
---|---|
Secure debugging is essential feature when you want to distribute |
.pdb
file stores the full paths of source files by default.
That's an excellent idea for an interactive debugger because it can find the source files easily.
However this can be an overhead when you only need stack traces or secure debugging.
That's why you may prefer to save some storage bits by using relative file paths.
They are shorter, as well as a resulting .pdb
file. Stack traces get shorter too, their readibility improves.
If you use automated error reporting then you will benefit from smaller workloads.
To use relative file paths, please supply [relative_file_paths]
flag to an obfuscation attribute like so in C#:
[assembly: Obfuscation(Feature = "debug [relative_file_paths]", Exclude = false)]
or in VB.NET:
<Assembly: Obfuscation(Feature:="debug [relative_file_paths]", Exclude:=False)>
Debug renaming is a special renaming technique for debugging of obfuscated applications. The result of this technique is the presence of human readable symbol names in output assemblies. Such symbol names allow to instantly watch variables and stack traces by an unaided eye.
Debug renaming works by applying _x_
prefix to every renamed class and class member. The name part after prefix equals to original item name.
Instructions on enabling debug renaming for an output assembly
- Open obfuscatable project inside the IDE
-
Add new source file to the project and
call it
ObfuscationSettings.cs
(for C#) orObfuscationSettings.vb
(for Visual Basic .NET). You may prefer to use another name instead ofObfuscationSettings.cs
orObfuscationSettings.vb
-
Fill
ObfuscationSettings.cs
with the following content (C#):using System; using System.Reflection; [assembly: Obfuscation(Feature = "debug renaming", Exclude = false)]
For Visual Basic .NET, fill
ObfuscationSettings.vb
with the following content:Imports System Imports System.Reflection <Assembly: Obfuscation(Feature:="debug renaming", Exclude:=False)>
Caution | |
---|---|
Debug renaming is exclusively a debugging feature. Never leave this feature enabled for production assemblies, otherwise original symbol names can leak to the outside world. |