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: Using Obfuscation Attributes With Dotfuscator

Reading Time: 2 minutes

In the Support Corner, we’ve seen coding patterns that require special Dotfuscator configuration. These configurations are typically stored in a DotfuscatorConfig.xml file. In certain circumstances, it may be preferable to use Obfuscation Attributes, which allow developers to inline obfuscation settings directly in the source code.

 

Please recall the Support Corner article “Protecting .NET applications that use Entity Framework,” which described how ORM frameworks map object names to database table names. Because of this, we exclude entity classes from Renaming to prevent a runtime exception after obfuscation:

Code Snippet for Support Corner: Using Obfuscation Attributes with Dotfuscator

 

These exclusions could be translated into Obfuscation Attributes:

Code Snippet for Support Corner: Using Obfuscation Attributes with Dotfuscator

 

and 

Code Snippet for Support Corner: Using Obfuscation Attributes with Dotfuscator

 

By translating to Obfuscation Attributes, we identify and remediate the potential runtime exception without touching the build server. We don’t even need to install Dotfuscator, because the Obfuscation Attribute is defined in the System.Reflection namespace. When this code is sent to the build server, Dotfuscator reads and honors the Obfuscation Attributes. If additional settings are supplied in a DotfuscatorConfig.xml, the rules will be logically ORed together.

 

As developers working on the codebase daily, we can set configurations earlier than DevOps Engineers or Build Managers. Adding Obfuscation Attributes in code can spare testing, debugging, and configuration — and save time later in the process.

 

If you have feedback on this topic or other topics you would like us to discuss in the Support Corner, please contact us at support@preemptive.com.

 


 

 

Categories
DashO DevSecOps Support Corner

Support Corner: Use Make Synthetic in DashO

Reading Time: 2 minutes

Application security is an ever-evolving arms race: bad actors constantly try to circumvent protections, while good actors constantly work to stop them. To be most effective, every app security strategy should employ defense-in-depth. PreEmptive provides several distinct layers of protection, such as Renaming, Control Flow, String Encryption, and Tamper Defense. Make Synthetic is another handy feature, but it should be used only in certain contexts.

 

Make Synthetic causes a class, method, or field to appear compiler-generated. Because of this, decompilers cannot correctly render code, and often choose to skip these sections altogether. This closes another avenue a hacker could use to spy on code.

 

As with other obfuscation transforms, Make Synthetic is fully configurable. It can be enabled or disabled independent of other protections. You also have the granular control to include or exclude packages, classes, methods, and fields:

If you’re creating a library or exposing an API, Make Synthetic should not be used because it may impact how external callers work. For this reason, it is disabled by default as part of PreEmptive’s “first do no harm” principle. If your app is fully self-contained, Make Synthetic can be explicitly enabled in the DashO project settings.

 

As decompilers evolve, we constantly observe how they respond to obfuscated code. When used effectively, DashO’s Make Synthetic feature provides another distinct layer of protection as part of an overall defense-in-depth strategy.

 

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

 


 

 

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

Support Corner: How to Leverage Custom Rules in Dotfuscator

Reading Time: 2 minutes

PreEmptive has evolved through the years to handle all different types of applications and scenarios. Reasonable defaults are designed to get any project up and running, and from there we have full control over protection settings. Custom rules are one way to create simple, robust, flexible configurations — even with very complex applications.

In previous Support Corner articles, we learned about coding techniques that require a Rename exclusion to run properly after obfuscation. Sometimes, excluding just one class, method, field, or property is sufficient. But for larger, more complex applications this is usually not the case. Custom rules can help organize these exclusions into patterns for a more flexible and robust configuration. Rules can be created to exclude all descendants of a parent class or those that implement a particular interface. Rules can be created for types or members decorated with a custom attribute, or those that have a certain access modifier. Regular expressions can also be used to make custom rules based on the naming convention.

Consider the following example.

In “Protecting .NET applications that use the MVVM pattern,“ we learned that MVVM uses reflection to load properties of model classes: 

Because of this, we had to exclude those properties from Rename obfuscation to avoid a runtime error:

Rather than checking individual checkboxes for each property, I can translate this into a custom rule. Each model classes with an OnPropertyChanged method must implement INotifyPropertyChanged. Based on this, I will write a rule to exclude properties (.*) of any type (.*) that implements INotifyPropertChanged:

By making this modification, we can change or expand use of the MVVM pattern without having to update obfuscation rules. I will also apply the other obfuscation transforms String Encryption, Control Flow, Linking, and Tamper defense to secure that section of code.

The full MVVM example modified to use Custom Rules can be downloaded here.

The original Support Corner article “Protecting .NET applications that use the MVVM pattern” is here.

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

 


 

 

Categories
Support Corner

Support Corner: Protecting React Native Apps

Reading Time: 3 minutes

We’ve recently worked with a handful of customers in the process of creating React Native apps. As with other mobile development frameworks, it is relatively easy to reverse engineer and tamper with React Native apps. For this reason, it’s essential to secure your organization’s IP and data before publishing. In the following article, we’ll discuss how to do so using PreEmptive.

React Native apps are primarily written in JavaScript, then packaged as an APK, AAB, or IPA file for deployment. Once the app is installed on a device, the end user can extract an APK and see the bundled JavaScript file within the “assets” directory. The bundle will be minified during the build, but this can easily be unminified and formatted by a text editor such as Nodepad++ with JSTool. Doing so would reveal API calls, keys, and sensitive strings:

JavaScript can also interface with Native Java modules. Java is compiled and embedded in the APK as one or more classes.dex file(s). A tool such as ByteCode viewer can decompile the classes.dex to reveal sensitive IP within Java source:

Leaving code exposed in such a way is quite dangerous. A hacker could clone the app, infiltrate back-end systems, initiate a data breach, and more. Luckily, PreEmptive can protect the code embedded in the APK. JSDefender for JavaScript can protect the JavaScript bundle. DashO Java obfuscator can protect the Java code.

JSDefender’s Metro plugin and DashO’s Gradle plugin integrate protection directly into our build.

metro.config:

build.gradle:

When building the React Native project

>npx react-native run-android 

or 

>gradlew clean assembleRelease or bundleRelease


PreEmptive can be seen running in the build output:

After this build, binary is hardened against decompilation, reverse engineering, and tampering:

The full source code sample can be downloaded here.

In order to run the sample:

  • Download the JSDefender (trial or commercial) Core and Metro npm packages. 
  • Configure the JSDefender license key in jsdefender.config.json. 
  • Install and register PreEmptive DashO (trial or commercial) on your machine.
  • Run npm install within the directory. 

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

 

 

 

 

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.