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.


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.