Protecting Xamarin-based applications against reverse-engineering, cloning and cracking

Xamarin is one of the most popular frameworks used for cross-platform mobile app development. It allows software developers to share about 90 percent of code across major platforms (Android, iOS, Windows apps).

DexProtector supports the protection of Xamarin applications (available with an Enterprise license). This is a guide to using DexProtector to protect your Xamarin-based applications.

Every feature of DexProtector Enterprise is available for Xamarin-based Android apps, including:

  • Code hardening and resource hardening through obfuscation and encryption of classes, methods, and strings, to prevent static analysis and reverse engineering
  • Runtime Application Self-Protection (RASP), with constant checks on the operating environment and communications network, to prevent dynamic analysis and Man-in-the-Middle attacks
  • Integrity checks, to prevent code and resource tampering and cloning
  • DexProtector's dedicated CryptoModule, isolating cryptographic data and processing to prevent interception of cryptographic keys and calculations

Xamarin Android applications contain Dalvik bytecode, resources and native libraries. Within the resources there are Mono Runtime native libraries and Xamarin Assemblies. Xamarin Assemblies consist of Xamarin Runtime and Xamarin Program Code.

Applying DexProtector Protection mechanisms to Xamarin-based Android Applications

1. Code Hardening

Our fundamental defenses against static analysis work on Dalvik bytecode within Xamarin-developed Android apps, which may contain Android Wrapper Classes (Activity, ContentProvider, Receiver, Service), Xamarin/Mono support classes and third-party library classes:

  • String Encryption
  • Class Encryption
  • Hide Access

And for native libraries, DexProtector offers:

  • Native code obfuscation (excluding Mono Runtime)
  • Native code encryption
  • Native code anti-debugging (gdb).

DexProtector is also capable of interacting with Mono Runtime, thereby allowing you to encrypt Xamarin assemblies. You can use the <xamarinAssemblies/> node in the DexProtector configuration file to enable the encryption of assemblies. For example:

        <xamarinAssemblies dir="custom assemblies location">
                       <filters>
                            <filter>EnvironmentCheckXamarin.dll</filter>
                       </filters>
        </xamarinAssemblies>

Please see the full description of the settings in the documentation.

2. Content Protection

All the mechanisms DexProtector provides for content protection are applicable for protection of Xamarin-based Android apps:

  • Encryption of resources and assets
  • Resource name obfuscation (resources.arsc)
  • Obfuscation of AndroidManifest: Applications/ActivityNames/ContentProviders/Receivers class names mangling

3. Integrity Control

DexProtector provides the most reliable integrity control (tamper-proofing) mechanisms. The integrity control works by default, out of the box for Xamarin-based applications, as it does for any other Android or iOS app.

4. Environment Checks

To implement DexProtector's environment checks for Xamarin-based apps, we recommend using Android Callable Wrappers.

First of all, it is necessary to configure Xamarin so that it uses Android-style naming for the Activity class in which you will place Probe and Callback methods.

[Activity(Name = "environmentChecksXamarin.MainActivity", ...]
    public class MainActivity : Activity

Note: The first character in the exported name must be lower case.

Then you must export all the required methods:

        [Export]
        public static void doProbe(Context ctx)
        {
            System.Console.WriteLine("doProbe: "+ctx);
        }

        [Export]
        public static void positiveRootCheck(Object data)
        {
            System.Console.WriteLine("positiveRootCheck data: " + data);
            envChecks.Set((int)EnvCheckType.Root, true);
        }

As a result, Xamarin will generate Android Wrapper code that looks like this:

package environmentChecksXamarin;


public class MainActivity extends Activity implements IGCUserPeer {
    public static final String __md_methods = "n_onCreate:(Landroid/os/Bundle;)V:GetOnCreate_Landroid_os_Bundle_Handler\nn_doProbe:(Landroid/content/Context;)V:__export__\nn_positiveRootCheck:...";

    private ArrayList refList;

    private static native void n_doProbe(Context context);

    private static native void n_positiveRootCheck(Object obj);

    ...

    static {
        Runtime.register("EnvironmentChecksXamarin.MainActivity, EnvironmentChecksXamarin", MainActivity.class, __md_methods);
    }

    public void onCreate(Bundle bundle) {
        n_onCreate(bundle);
    }

    public static void doProbe(Context context) {
        n_doProbe(context);
    }

And here is the clever part: invoking the Probe method correctly. At first glance, it might appear that the following C# code would be enough:

        protected override void OnCreate(Bundle savedInstanceState)
        {
            ..
            doProbe(this);
            ..
        }

But in this case, a different method will be invoked. Not the doProbe of the generated Java class, but a C# method n_doProbe(context) from Xamarin.

Just a little bit of JNI magic and the correct method is invoked:

            IntPtr class_ref = JNIEnv.FindClass("environmentChecksXamarin/MainActivity");
            IntPtr method_ref = JNIEnv.GetStaticMethodID(class_ref,
                                                         "doProbe", "(Landroid/content/Context;)V");
            JNIEnv.CallStaticVoidMethod(class_ref, method_ref,new JValue(this));

And from a security point of view, it is highly important that the Java class that contains doProbe and positive/negative callbacks is protected with String Encryption, HideAccess, ClassEncryption.

5. Secure Execution Environment

Secure Execution Environment is a self-defending secure native VM, designed to isolate cryptographic keys and processes. It is capable of running cryptographic operations inside our CryptoModule. It also has a HSM-like application pre-installed with White-Box Crypto key management system. If you are interested in the DexProtector SEE/CryptoModule as an additional feature for your app security, please request details via email - primary@licelus.com.