Categories
Support Corner

Support Corner: Protecting .NET Applications That Use Visual Studio Installer Projects

Reading Time: 2 minutes

 

The Visual Studio Installer project remains a popular way to deploy .NET applications. It is simple to configure and maintain, and it produces an MSI or EXE that can easily be distributed via a vendor website, software repository, or any other software distribution system.

The Challenge of Application Security

The installer project places managed assembly files on the end user’s machine. These files can easily be decompiled and reverse-engineered like other .NET applications. This is a significant problem if your app handles sensitive data, contains trade secrets, or has IP that needs to remain hidden.

Promote Security With Dotfuscator

The good news is this is easy to remediate. We just have to integrate Dotfuscator into our application’s .csproj or .vbproj project file.

Doing this will trigger Dotfuscator before the packaging steps of a Release build. Dotfuscator places obfuscated assemblies into the release directory, which will automatically be packaged for deployment by the Installer project. No additional steps are required.

This workflow can be implemented for Visual Studio installer projects and works for the most common project deployments: MSIX, ClickOnce, etc. Some projects, however, have non-standard approaches for creating installers. For example, the installer might be decoupled from projects building the assemblies. If this is the case, the Dotfuscator command line interface can be used to automate the handling of protected files.

Join the Conversation

If you have feedback on this topic or other topics you would like us to discuss in the Support Corner, please contact our Support Team. Your feedback is incredibly valuable to us and helps to shapes the conversations in our Support Corner so we can create a community of shared knowledge and mutual growth. We look forward to hearing from you!


 

Categories
Support Corner

Support Corner: Protect .NET Apps That Use P/Invoke Methods

Reading Time: 2 minutes

Dotfuscator works with the full range of application types – Desktop, Mobile, Cloud, and Internet of Things (IoT). It does this by setting sensible defaults, then providing complete granular control over obfuscation settings. Additionally, Dotfuscator understands specific coding patterns and automatically applies obfuscation rules wherever possible. One such example is Platform Invoke (P/Invoke).

What Is P/Invoke?

P/Invoke is a way of calling unmanaged C or C++ functions from a .NET program. This is useful if we have existing APIs written in C/C++, and we’re building new components in. NET. We can continue using the unmanaged codebase without rewriting while leveraging the power of the .NET ecosystem.

How Dotfuscator Handles P/Invoke

Dotfuscator has built-in rules to handle P/Invoke methods. If the original method name is used to find the corresponding native function, Dotfuscator preserves the method name to not break this mapping. On the other hand, if an alias, ordinal, or entry point is used, the P/Invoke method can safely be renamed without breaking runtime behavior.

Check Out This Example:

This .NET application has two calls to an unmanaged library via P/Invoke and the Dllimport attribute. The first method name maps to the corresponding native function. The second method uses the EntryPoint parameter to locate the native function:

 

After obfuscation, Dotfuscator renames myMethod to “a” but skips renaming the print_line method:

 

This occurs without any configuration needed from the user. On a project-wide scale, this ensures Dotfuscator applies the maximum renaming possible, while not breaking runtime behavior.

Wrapping It Up

P/Invoke is one example of how Dotfuscator automatically applies obfuscation rules, saving time and effort during project configuration.

The above example can be downloaded here.

If you have any feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.


 

Categories
Support Corner

Protecting C# Applications That Use Friend Assemblies

Reading Time: 2 minutes

The internal keyword in C# restricts access of types and members to callers in the same assembly. The InternalsVisibleTo attribute is a special way to grant internals access to a “Friend” assembly. Friend assemblies are used when unit testing, as internal members must be directly invoked by a test DLL. So it is quite common to have several friend assemblies in our project.

 

Dotfuscator takes friend assemblies into consideration when applying protection settings. It follows a specific process to preserve runtime behavior while performing as much obfuscation as possible. It also notifies us of any potential issues with friend assemblies during the build.

 

Please consider the following example, a DLL has InternalsVisibleTo an EXE file:

 

 

The EXE file directly references an internal class, made possible only by adding the InternalsVisibleTo attribute in the DLL: 

When obfuscating only the DLL, one of the following warnings would be shown, depending on the Dotfuscator configuration:

 

WARNING: MyAssembly has non-input Friend Assemblies and is in Library Mode; internal members will not be renamed or pruned. Consider adding Friend Assemblies as input for increased obfuscation.

OR 

WARNING: MyAssembly has non-input Friend Assemblies and is not in Library Mode; internal members may be renamed or pruned. References from non-input Friend Assemblies to the internal members of MyAssembly may no longer be valid.

 

The first message occurs when Dotfuscator is run in Library Mode. In Library Mode, Dotfuscator will not rename public and protected members for reusability of obfuscated components (as with APIs). Because of the InternalsVisibleTo attribute, Dotfuscator will also skip the renaming of internals. This will result in less Rename obfuscation than we may have anticipated, but it also will not break any runtime behavior. 

 

The second message warns that Dotfuscator may rename internals in a way that could break calls from the friend assembly.  If the friend assembly is deployed with this obfuscated DLL, this could cause a runtime error. If the friend assembly is not deployed (as with a unit testing DLL) then this warning will have no runtime impact and can be disregarded.

 

In general, obfuscation works best when more parts of the application are obfuscated together. The above warnings will completely disappear if the friend assembly is included as Dotfuscator input. If this is not feasible, we can still process the assemblies in Library mode but with less obfuscation.

 

The full example can be downloaded here.


Be on the look out for our next Support Corner blog!

 

Categories
Support Corner

Support Corner: Protecting .NET Applications That Use Custom Attributes

Reading Time: 3 minutes

Attributes are used for many different things in .NET: unit testing, serialization, language interoperability, etc.

.NET also provides the ability to create custom attributes. This can be used for building our own object mapping (ORM), custom serialization mechanisms, or other distinguishing objects for a specific purpose.

Protecting .NET applications that use custom attributes is a seamless process with Dotfuscator. Dotfuscator cloaks attribute definitions and automatically updates references throughout the application, so the name remains hidden. If the attribute is defined in an external library (not included in obfuscation), Dotfuscator automatically preserves the attribute usage within its inputs. 

This default behavior handles most scenarios involving attributes. But there are times when a custom configuration is necessary. Fortunately, Dotfuscator’s rules engine gives us the flexibility to handle any unique scenario involving custom attributes.

Please consider the following example app:

A custom PermissionRequiredAttribute has been created to distinguish features requiring special permission:

After protecting with Dotfuscator, the PermissionRequiredAttribute, along with all references, are hidden:

Equally as important, the app runtime behavior works properly after protection:

The above scenario works great. But other times, Dotfuscator configuration is required. For example, if PermissionRequiredAttribute is loaded by an external reference not included in obfuscation, we would need a rule to preserve PermissionRequiredAttribute from Renaming. 

In another example, types decorated by PermissionRequiredAttribute are serialized, but the deserialization mechanism is not obfuscated. In this case, rather than excluding the custom attribute itself, we would create a rule to exclude any type (or member) decorated by PermissionsRequiredAttribute:

Custom attributes are yet another powerful component of the .NET platform and, when used effectively, save time and lines of code. Protecting apps that use custom attributes is simple when we take note of the guidelines above.

You can download the complete sample code here.


If you have feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.


 

Categories
Support Corner

How to Leverage Incremental Obfuscation when Protecting Large Applications

Reading Time: 2 minutes

In the previous Support Corner article, we discussed the significance of Cross-Assembly Obfuscation when configuring Dotfuscator.  Cross-Assembly Obfuscation ensures that classes, methods, properties and their references are automatically renamed uniformly across all Dotfuscator inputs.

Separated Assemblies Obfuscated

When related assemblies are obfuscated separately, they’re processed in Library Mode by default.  Library Mode does not rename public and protected types and members so that they can still be called by assemblies not included in that Dotfuscator project.  (Obfuscation transforms like Control Flow, String Encryption, and Tamper detection will be performed regardless of access modifier).

What if the different components of our app must be obfuscated as separate projects, but we still want to fully rename public types and members? This can be achieved by using Incremental obfuscation.

Incremental obfuscation

Incremental obfuscation uses Dotfuscator’s Rename Map file to maintain consistent identifier renaming across Dotfuscator builds.  It was created to enable patching a subset of assemblies for an obfuscated app already in production.  It can also be used to rename serializable types, so that full Renaming can still be performed on apps that persist serializable types to file. 

Along these same lines, Incremental Obfuscation can be used to maximize renaming when separating components of an app into multiple Dotfuscator projects.  

Example:

Consider the following example: a company maintains a set of common assemblies used by several different projects.  Each project has completely different sprints and release cycles.  In this scenario, the team maintaining the common assemblies uses Dotfuscator to fully obfuscate and rename publics.  They store the Rename Map file with their build artifacts.  Any team creating a front-end app will use that map file to rename references to the shared assemblies in their Dotfuscator project.  Only the map file is needed – they do not need to re-obfuscate the common assemblies.  When it’s time to deploy to production, all public and protected types and members for the full application will be renamed.

A simple example illustrating this concept can be downloaded here.


If you have feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.


Categories
Support Corner

Understanding Cross-Assembly obfuscation

Reading Time: 2 minutes

Enterprise application development involves several moving parts.  There may be different teams working on different components: server-side, client-side, GUI, API, database, etc.  Each component may have a completely different release cycle, and each team may be working completely independent of one another.  But however the work is divided, all these components must come together to work properly at runtime. Any professional application protection tool should have the ability to handle these complex scenarios without disrupting the development process.  

Dotfuscator’s Runtime

Dotfuscator is designed with that at the center. The tool allows users to get up and running quickly, while providing full control to adjust for specific project requirements.  Cross-Assembly Obfuscation is just one example of the many ways it provides us this flexibility. 

Dotfuscator treats its inputs as a set of related assemblies.  It examines all internal and external references, traverses the full inheritance hierarchy.  It then performs “Cross-Assembly Obfuscation” meaning classes, methods, properties and their references are renamed uniformly across all input assemblies.

Dotfuscator Flexibility

If it’s not feasible to obfuscate and deploy our entire application at the same time, this is not a problem for Dotfuscator.  It can be approached a few different ways, but the easiest to maintain is to build with Library Mode enabled for each project.  In Library Mode, Dotfuscator preserves public and protected types and member names and signatures.  Only private and internal types and members will be renamed.  Obfuscation transforms like Control Flow, String Encryption, and Tamper detection will be performed regardless of access modifier.  This ensures that calls to the obfuscated assemblies work properly whether the calling assembly has been obfuscated in the same project or not.  

Cross Assembly Obfuscation Example

A simple example can be downloaded here.  This shows the same set of assemblies (two dll’s referenced by one main exe) obfuscated two different ways.  In the first scenario, all assembly files are included in one Dotfuscator project.  In the second scenario, each assembly is obfuscated separately, with Library Mode enabled to preserve references between them.  In both scenarios, the obfuscated binaries come together to work properly at runtime. 


Stay tuned for our continuation article, we will examine other strategies for approaching obfuscation spanning different teams.  If you have feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.


Categories
Support Corner

Protecting a ClickOnce Deployed Application

Reading Time: 2 minutes

ClickOnce is a popular way to deploy and keep applications up to date without a lot of hassle.  These applications are downloaded to the end user’s machine after being published to the server, which means they can easily be decompiled and reverse engineered like other .NET applications. 

Protecting an application that is deployed via ClickOnce is usually very complicated.  After protection, the application and deployment manifests must be manually updated using the Mage tool.  Signing of manifests and assembly files must be done manually, as well. 

With Dotfuscator, we’ve worked to make this process much simpler.

Consider this Example

In 4x versions, Dotfuscator accepted the ClickOnce .application as direct input.  It would re-generate the obfuscated assemblies along with the updated .application package.  The updated deployment manifest and protected binaries would then be copied to the ClickOnce deployment server to be downloaded by the end-user.

Starting with version 6, we’ve made this process even easier.  We just have to integrate Dotfuscator into our application’s project file (.csproj, .vbproj).    

Doing so triggers Dotfuscator to run before packaging steps of our Release build.  Protected binaries are then automatically packaged for deployment.  No additional steps required.

We’ve worked with customers that deploy through ClickOnce, and also create an installer for offline installs.  This process allows us to do both without any additional steps.

A simple ClickOnce project with Dotfuscator integration can be downloaded here.  A release publish of this project generates obfuscated binaries.  Double-clicking the .application manifest simulates a download and install of the ClickOnce application on the client’s machine.

If you have feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.


Categories
Support Corner

Remove Log4J calls with DashO’s Method Call Removal

Reading Time: 3 minutes

As we all know Log4j is a ubiquitous piece of software used to record activities in a wide range of systems found in consumer facing products and services. The discovery of the recent vulnerability in the Java logging package (CVE-2021-4428) This risk posed a severe threat to millions of consumer products from enterprise software to web applications. It presents risk of loss, or breach of personal information, financial loss and irreversible reputation harm. Currently, the FTC is taking action to require organizations to settle any associated risk caused by the known vulnerabilities. The FTC is now noted as using its full legal authority to pursue companies that fail to take reasonable steps to protect consumer data from exposures. 

A recent example of this negligence came on the back of a complaint in regards to Equifax’s failure to patch a known vulnerability which irreversibly exposed the personal identifiable information of 147 million consumers. This resulted in Equifax paying $700 million to settle the actions taken by the FTC and the consumer financial protection bureau. The risk for businesses is therefore clear, take actionable steps to remediate the vulnerability, or face litigation, breach risk and reputation damage.

In this guide, we will walk you through how you can use Method Call Removal to mitigate this vulnerability.

Method Call Removal

Method Call Removal has been available since our DashO 6.11 release.  It is mostly used for removing logging statements, but it can be used to strip any method calls we’d prefer not to have in our production release.  The only caveat is that the method definition must also be in DashO’s input.

Let’s assume Log4j is used for our application’s logging.  We might want to remove all log statements from production builds, then create special debug builds with logging enabled as needed.  Or, we might want to remove Info, Warn, and Debug messages, but retain Error or Fatal message in our production build.  This can be done using DashO’s Method Call Removal feature, without needing to adjust the Log4j configuration.

Please consider the following example:

This application logs informational messages when the app starts, and when it shuts down.  

The Log4J configuration has been organized into a global logging class:

In our DashO project, I’ll select the “LogInfo” method for method call removal:

Graphical user interface, text, application
Description automatically generated

After doing so, the application runs normally, but informational messages are no longer logged to console or written to log file.

After the app has been in production, I may need to create an obfuscated debug build for troubleshooting an issue with a specific client.  If so, I can run DashO without Method Call Removal to preserve logging calls in my debug build.

The above example can be downloaded here.


If you have any feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.


Categories
Support Corner

Protecting VSTO Add-Ins

Reading Time: 2 minutes

Visual Studio Tools for Office (VSTO) have enabled .NET developers to extend the functionality of Office applications like Word, Outlook, and Excel since 2003.  VSTO Add-Ins are deployed directly to the end user’s machine and triggered when the Office application starts.  Because of this, VSTO Add-Ins can be easily decompiled and reverse engineered like other .NET applications. As many developers can attest, this is an easy access point for hackers to gain control of your applications.

Most application hardening techniques are quite cumbersome for VSTO Add-Ins.  After application hardening, the VSTO application manifest (.manifest) and deployment manifest (.vsto) must be manually created or updated using the Mage tool.  Signing of assembly and manifest files must be done separately as well. 

Protecting VSTO Add-Ins

Fortunately, protecting VSTO Add-Ins is made simple with PreEmptive’s Dotfuscator.  All we have to do is edit the project file (.csproj, .vbproj) to add tags that call Dotfuscator.

This will trigger Dotfuscator to run before packaging steps of our build, so protected binaries are automatically packaged for deployment.  This works whether we’ve created an installer or are using ClickOnce.  No additional steps are required and developers can implement it relatively easily.

Example of VSTO Add-In

A simple VSTO Add-In with Dotfuscator integration can be downloaded here.  A release build automatically generates obfuscated binaries, and double clicking the .vsto manifest installs the Word Add-In.

Although VSTO Add-Ins are being phased out in favor of the new Office Add-in, there are still several VSTO applications in production which could benefit from Dotfuscator’s simple integration. If you have questions on this or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department


Categories
Dotfuscator Support Corner

Protecting Windows Forms Applications with Data Bound GUI Controls

Reading Time: 3 minutes

Today we will focus on data binding, but first let’s define this. Data binding allows Windows Forms applications to display and update UI controls from a data source, without having to modify source code for the control itself. 

When protecting Windows Forms applications, it is important to note how the data bound controls are constructed to determine if they will be impacted by code obfuscation.  If the controls bind to a collection of objects, original property names of that object must be preserved to correctly populate “DisplayMember” and “ValueMember” properties of the control.  When binding controls to an Enum, the original names of its members must be preserved, or the GUI control might show obfuscated names.  On the other hand, if we’re binding directly to a database table (and the table does not map to an object in source code), we don’t need any custom configurations because Dotfuscator does not mangle table and column names.

Consider the Following Example:

This simple Windows Forms application has three UI controls with different data binding techniques: a DataGridView binds to a Customer table in a database, a ListBox binds to a collection of Employee objects, and ComboBox binds to an Enum called DaysOfWeek:  

If I obfuscate with project defaults, I experience a runtime error at app startup:

This occurs because original property names of the Employee object are used in “DisplayMember” and “ValueMember” ListBox properties:

            listBox1.DataSource = employeeList;

            listBox1.DisplayMember = “Name”;

            listBox1.ValueMember = “Department”;

To Avoid the Runtime Error:

First, I’ll open my project configuration file (DotfuscatorConfig.xml) in the Dotfuscator Config Editor, and set a Rename exclusion for the properties in the Employee object:

After configuring this Rename exclusions, the application starts without the runtime exception, but the “DaysOfWeek” ComboBox appears with obfuscated names:

In order to fix this, I will configure a Rename exclusion for the members of DaysOfWeek.

After providing this Rename exclusion, the app starts without any issues or erroneous behavior.  Please also note the DataGridView, which binds to the Customer table in our database, did not require any Rename configuration to start and display correctly.

Conclusion

There are several different ways to use data binding in Windows Forms applications.  We’ve seen a few ways that data bound controls can be impacted by obfuscation.  If you experienced a runtime crash or erroneous UI behavior after applying obfuscation, please use the above steps to resolve the issue. 

The full example can be downloaded here.

If you have any feedback on this topic or other topics you would like us to discuss in the Support Corner, please feel free to contact our Support Department.